File: DIFRKMTY\A_EXTERN.CPP

    1 //##############################################################################
    2 //                                                                            //
    3 // A_EXTERN.CPP                                                               //
    4 //                                                                            //
    5 // Subsystem: Diffraktometrie/ Reflektometrie                                 //
    6 //            DAS MDI-Fenster für AreaScan                                    //
    7 // Benutzung durch andere Subsysteme erforderlich: JA                         //
    8 //                                                                            //
    9 //##############################################################################
   10 //! Kommentierung und Aenderungen B. Buss, 2000/2001, HUB IfI
   11 
   12 #include <direct.h>
   13 
   14 #include "internls\evrythng.h" // GermanVersion
   15 #include "winresrc\rc_def.h"   // Ressourcen-IDs
   16 #include "help\help_def.h"     // Help-IDs
   17 #pragma hdrstop
   18 
   19 #include "difrkmty\a_extern.h" // SCHNITTSTELLE für diese Datei
   20 
   21 #include "datavisa\datavisa.h"
   22 #include "motrstrg\motrstrg.h"
   23 #include "workflow\workflow.h"
   24 #include "difrkmty\a_intern.h" // TChooseScanDlg, TSetupAreaScanDlg, ...
   25 
   26 #include "internls\l_layer.h" // 17.11.2002 für extern lpDBase
   27 
   28 //! neu: klier Allgemeine Einstellungen
   29 #include "mespara\mespara.h"
   30 
   31 //! neu: klier Protokollbuch
   32 #include "protocol\protocol.h"
   33 
   34 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   35 
   36 __declspec(dllimport) LPDataBase lpDBase;
   37 __declspec(dllimport) LPMList lpMList; //Komposition aus TMotor-Objekten
   38 
   39 extern TMain Main; // in m_MAIN.CPP deklariertes Hauptprogramm
   40 extern TSteering Steering;
   41 
   42 //! neu: klier Allgemeine Einstellungen
   43 extern TMeasurementParameter MeasurementParameter;
   44 
   45 //#############################################################################
   46 // globale Typen und Konstanten
   47 //#############################################################################
   48 
   49 struct TData // variables for data aquisition
   50 {
   51         double dX, dY, dOmega, dTheta;
   52         float fDelta, fIntensity;
   53 };
   54 
   55 TModelessDlg* ChooseScanDlg= 0; //! neu Kullmann+Reinecker: TheModeless ersetzt durch ChooseScanDlg; extern entfernt
   56 
   57 // #define Peak_and_Cross
   58 
   59 //#############################################################################
   60 // sprachspezifische Konstanten
   61 //#############################################################################
   62 
   63 #ifdef GermanVersion
   64   static const char szMsgFailure[]= "Fehler";
   65   static const char szMessage[]= "Meldung";
   66 
   67   static const char szTitle[]= "AreaScan: ";
   68 
   69   static const char szMsgLine001[]= "Messung! Omega: %s 2Theta: %s Intensität: %%.3f";
   70   static const char szMsgLine002[]= "Der Detektor %s ist als Monitor gekennzeichnet!";
   71   static const char szMsgLine003[]= "Starte Omega/2Theta-Scan(PSD) \nmit Omega von %s bis %s ?";
   72   static const char szMsgLine004[]= "Starte Omega/2Theta-Scan(SLD) \nmit Omega von %s bis %s ?";
   73   static const char szMsgLine005[]= "Starte OmegaScan(PSD) \nmit Omega von %s bis %s ?";
   74   static const char szMsgLine006[]= "Theta ist relativ! \nOffset berücksichtigen ?";
   75   static const char szMsgLine007[]= "Omega ist relativ! \nOffset berücksichtigen ?";
   76   static const char szMsgLine008[]= "Scan-Nummer übersteigt %d !";
   77   static const char szMsgLine009[]= "Messung! Omega: %s";
   78   static const char szMsgLine010[]= "%s P(%s<>%%.1f) Integral Intensität: %%.1f > %%d";
   79   static const char szMsgLine011[]= "%d Scan's wurden gemessen";
   80   static const char szMsgLine012[]= "Die Messung wurde abgeschlossen \nund gespeichert.";
   81   static const char szMsgLine013[]= "Messung wurde unterbrochen !";
   82   static const char szMsgLine014[]= "Inkorrekter Header.";
   83   static const char szMsgLine016[]= "Kein Detektor als Monitor spezifiziert!";
   84   static const char szMsgLine222[]= "Messung wurde abgebrochen !";
   85 
   86   //! neu eingefuehrt
   87   static const char szMsgLine017[]= "Bitte erst Daueranzeige deaktivieren!";
   88   static const char szMsgLine018[]= "Die Messung wurde abgeschlossen.";
   89   static const char szMsgLine019[]= "Die Messung wurde abgeschlossen. \r\nFehler beim Speichern!";
   90   static const char szMsgLine020[]= "Es ist ein Fehler aufgetreten. %d";
   91   static const char szMsgLine021[]= "Hardware ist nicht vollständig verfügbar !";
   92   static const char szMsgLine023[]= "Ungültiger Darstellungstyp !";
   93   static const char szMsgLine024[]= "Kein Psd verfügbar !";
   94   static const char szMsgLine025[]= "Standard-Scan nur mit PSD.";
   95   static const char szMsgLine026[]= "Anzeige Psd-Spektrum ...";
   96   static const char szMsgLine026e[]= "Psd-Energiespek...";
   97   static const char szMsgLine026p[]= "Psd-Pos.-Spek...";
   98   static const char szMsgLine027[]= "Bitte die Darstellung >Curve< waehlen.";
   99   static const char szMsgLine028[]= "Scan %d von %d schreiben.";
  100   static const char szMsgLine029[]= "Scan %d schreiben.";
  101   static const char szMsgLine030[]= "Reportdatei \n\"%s\" \nfehlt oder ist defekt!";
  102   static const char szMsgLine031[]= "keine Datenbasis vorhanden";
  103 
  104   //! neu: klier Protokollbuch
  105   static const char szMsgLine032[]= "Soll die Messung im Protokollbuch gespeichert werden?";
  106 
  107   static const char szMsgLine200[]= "gewählte Koordinaten außerhalb des Meßgebiets!";
  108   static const char szMsgLine201[]= "Eingabe wird verworfen !";
  109   static const char szMsgLine202[]= "[Header] \nGerade zwischen 2 Punkten \n";
  110   static const char szMsgLine203[]= "RLY aufsteigend geordnet\n";
  111   static const char szMsgLine204[]= "Probleme beim Anlegen der Datei !";
  112   static const char szMsgLine205[]= "Omega aufsteigend geordnet\n";
  113   static const char szMsgLine206[]= "Die Daten wurden in Datei %s gespeichert !";
  114   static const char szMsgLine207[]= "Daten-Erhebung - Information";
  115   static const char szMsgLine208[]= "Start AreaScan";
  116   static const char szMsgLine209[]= "Psd-Spektrum anzeigen";
  117   static const char szMsgLine210[]= "Datei nachladen";
  118   static const char szMsgLine211[]= "%d Scan's gelesen";
  119   static const char szMsgLine212[]= "archivierte Datendatei wurde gelesen";
  120   static const char szMsgLine213[]= "PSD-Kalibrierung";
  121 
  122   // x-Achse
  123   static const char szChannel[]=   "Kanäle von %s";
  124   static const char szAngle[]=     "Winkel von %s";
  125   static const char szAngleUnit[]= "Winkel von %s\nin %s";
  126   static const char szAngleUnitEZ[]= "Winkel von %s";
  127   // y-Achse
  128   static const char szAngleOmegaUnit[]= "Winkel von\n%s\nin %s";        
  129   static const char szAngleOmegaUnitEZ[]= "%s"; 
  130   static const char szEnergy[]=         "Kanäle";
  131   static const char szFrequentLi[]=     "Häufigkeiten\nlinear skaliert";
  132   static const char szFrequentLo[]=     "Häufigkeiten\nlog10 skaliert";
  133 
  134   static const char szMsgLine312[]= "Ein kontinuierliches PSD-Spektrum wird gerade angezeigt.\nUm die PSD-Kalibrierung aufrufen zu können, muss diese Anzeige gestoppt werden.\n\nMöchten Sie das kontinuierliche PSD-Spektrum jetzt automatisch stoppen lassen?";
  135   static const char szMsgLine313[]= "Dateiheader wird gelesen...";
  136   static const char szMsgLine314[]= "Messdaten werden ausgewertet...";
137 #else 138 static const char szMsgFailure[]= "Failure"; 139 static const char szMessage[]= "Message"; 140 141 static const char szTitle[]= "AreaScan: "; 142 143 static const char szMsgLine001[]= "Measurement! Omega: %s 2Theta: %s Intensity: %%.3f"; 144 static const char szMsgLine002[]= "The Detector %s is tagged as Monitor !"; 145 static const char szMsgLine003[]= "Starting Omega/2Theta-Scan(PSD) \nwith Omega from %s to %s ?"; 146 static const char szMsgLine004[]= "Starting Omega/2Theta-Scan(SLD) \nwith Omega from %s to %s ?"; 147 static const char szMsgLine005[]= "Starting OmegaScan(PSD) \nwith Omega from %s to %s ?"; 148 static const char szMsgLine006[]= "Theta is relative! \nDo you want to use the Offset ?"; 149 static const char szMsgLine007[]= "Omega is relative! \nDo you want to use the Offset ?"; 150 static const char szMsgLine008[]= "Scan-Number exceeds %d !"; 151 static const char szMsgLine009[]= "Measurement! Omega:%s"; 152 static const char szMsgLine010[]= "%s P(%s<>%%.1f) Integral Intensity: %%.1f > %%d"; 153 static const char szMsgLine011[]= "%d Scan's has been measured"; 154 static const char szMsgLine012[]= "The Measurement is completed \r\nand the data were saved."; 155 static const char szMsgLine013[]= "Measurement has been interrupted !"; 156 static const char szMsgLine014[]= "Incorrect Header."; 157 static const char szMsgLine016[]= "No Detector as Monitor specified!"; 158 static const char szMsgLine222[]= "The Measurement was stoped !"; 159 160 //! neu eingefuehrt 161 static const char szMsgLine017[]= "Please deactivate Continuousdisplay first"; 162 static const char szMsgLine018[]= "The Measurement is completed."; 163 static const char szMsgLine019[]= "The Measurement is completed. \r\nFailure on saving data."; 164 static const char szMsgLine020[]= "There is a Failure appeared. %d"; 165 static const char szMsgLine021[]= "Hardware is not complete available !"; 166 static const char szMsgLine023[]= "Invalid Display Type !"; 167 static const char szMsgLine024[]= "No psd available ."; 168 static const char szMsgLine025[]= "Standard-Scan with PSD only"; 169 static const char szMsgLine026[]= "Display Psd-spectrum ..."; 170 static const char szMsgLine026e[]= "Psd-energyspec..."; 171 static const char szMsgLine026p[]= "Psd-pos.-spec..."; 172 static const char szMsgLine027[]= "Please choose the Display-type >Curve< ."; 173 static const char szMsgLine028[]= "Save Scan %d of %d ."; 174 static const char szMsgLine029[]= "Save Scan %d ."; 175 static const char szMsgLine030[]= "Reportfile \n\"%s\" \nis missing or damaged!"; 176 static const char szMsgLine031[]= "no DataBase existing"; 177 178 //! neu: klier Protokollbuch 179 static const char szMsgLine032[]= "Do you want to save this measure into the protocolbook?"; 180 181 static const char szMsgLine200[]= "selected coordinates outside of the measurementarea!"; 182 static const char szMsgLine201[]= "Input is rejected !"; 183 static const char szMsgLine202[]= "[Header] \nLine between 2 points \n"; 184 static const char szMsgLine203[]= "RLY ascending arranged\n"; 185 static const char szMsgLine204[]= "Problems when creating the file !"; 186 static const char szMsgLine205[]= "Omega ascending arranged\n"; 187 static const char szMsgLine206[]= "The data were stored in the file %s !"; 188 static const char szMsgLine207[]= "Data-inquiries - Information"; 189 static const char szMsgLine208[]= "Starting AreaScan"; 190 static const char szMsgLine209[]= "Show Psd-Spectrum"; 191 static const char szMsgLine210[]= "reload File"; 192 static const char szMsgLine211[]= "%d scan's read"; 193 static const char szMsgLine212[]= "archived data-file was read"; 194 static const char szMsgLine213[]= "PSD-Calibration"; 195 196 static const char szChannel[]= "channels of %s"; 197 static const char szAngle[]= "angles of %s"; 198 static const char szAngleUnit[]= "angles of %s\nin %s"; 199 static const char szAngleUnitEZ[]= "angles of %s"; 200 static const char szAngleOmegaUnit[]= "angles of\n%s\nin %s"; 201 static const char szAngleOmegaUnitEZ[]= "%s"; 202 static const char szEnergy[]= "channels"; 203 static const char szFrequentLi[]= "frequents\nlinear scaling"; 204 static const char szFrequentLo[]= "frequents\nlog10 scaling"; 205 206 static const char szMsgLine312[]= "A continuous Psd-Spectrum is displayed.\nIn order to run PSD-Calibration this display need to be stopped.\n\nDo you wish to stop the Psd-Spectrum automatic now?"; 207 static const char szMsgLine313[]= "reading fileheader..."; 208 static const char szMsgLine314[]= "translating measurementdata...";
209 #endif 210 211 //############################################################################# 212 // TAreaScanParameters 213 //############################################################################# 214 215 //! einlesen der Ini-daten zu [AreaScan] und setzen von default-werten fuer AreaScan 216 //! wird nur durch TAreaScanWindow-konstruktor aufgerufen 217 TAreaScanParameters::TAreaScanParameters() : Detector(0), Monitor(0) 218 { 219 char Ident[10]; 220 strcpy(Ident, "AreaScan"); 221 char buf[ MaxString ]; 222 int nOldId= mlGetAxis(); 223 224 //! setzen von Defaultwerten 225 strcpy( DataFile, "*.dtn" ); 226 eScanType= stOmega2ThetaScan; 227 228 // Initialisieren der Auswahlbox mit dem ersten nutzbaren PSD 229 SetDetector( TDetectorManager::DetectorManager().GetDetector(0, 1) ); 230 Monitor= 0; 231 232 if (GetPsd() != 0) 233 nAddedChannels= GetPsd()->GetAddedChannels(); 234 else 235 nAddedChannels= 1; 236 237 bThetaAddsPsd= TRUE; 238 fMaxTime= 6.0; 239 dwMaxCounts= 30000l; 240 eSaveFormat= ffStandardFile; 241 bSaveOnReady= FALSE; 242 bSaveContinuous= FALSE; 243 dMoveRelation= 2.0; 244 nOmega= mlGetIdByName( Omega ); 245 nTheta= mlGetIdByName( Theta ); 246 bAbsorberUsed= FALSE; 247 //! Werte fuer Datenbasis-Zusammensetzung 248 strcpy( FirstFile, "Kurve wählen!" ); 249 strcpy( LastFile, "TESTXXXX.CRV" ); 250 MaxFiles= 0; 251 252 ResetPosition(); 253 254 //! einlesen der Daten aus dem [AreaScan]-Abschnitt des Ini-Files 255 GetPrivateProfileString( Ident, "ExposureTime", "1.0", buf, MaxString, GetCFile() ); 256 fMaxTime= atof( buf ); 257 if ( CreateIniDefaults() ) 258 WritePrivateProfileString( Ident, "ExposureTime", buf, GetCFile() ); 259 260 //! FIX Fehler 37 261 bSaveOnReady= GetPrivateProfileInt(Ident, "SaveOnReady", 1, GetCFile() ); 262 //! FIX Fehler 56 263 //21.04.2004 eNotifyValue= nvIntegralIntensity; 264 //! auskommentiert von s.berndt j.ullrich 265 //! mit physikern noch zu klaeren, ob ganz entfernen oder aenderungswunsch 266 /*24.04.2004 GetPrivateProfileString( Ident, "Report", "Integral", buf, MaxString, 267 GetCFile() ); 268 strupr( buf ); 269 //! festlegen, welche Informationen neben dem Omegawinkel und dem Thetawinkel 270 //! als 3. wert im Scanreport gespeichert werden soll 271 while ( 1 ) { 272 eNotifyValue= PeakPosition; 273 if ( !strcmp( buf, "MONITOR" ) ) { 274 eNotifyValue= MonitorIntensity; 275 if ( ! TDList::DetectorList().->IsDetectorValid( MonitorDetector ) ) { 276 MessageBox( GetFocus(), szMsgLine016, szMessage, MBINFO ); 277 break; 278 } 279 Monitor= TDList::DetectorList().->GetDetectorPtr( ptrDetectorList->GetIdByName( MonitorDetector ) ); 280 break; 281 } 282 if ( !strcmp( buf, "ABSORBER" ) ) { 283 eNotifyValue= AbsorberPosition; 284 break; 285 } 286 if ( !strcmp( buf, "INTEGRAL" ) ) { 287 eNotifyValue= IntegralIntensity; 288 break; 289 } 290 if ( !strcmp( buf, "TIME" ) ) { 291 eNotifyValue= MeasurementTime; 292 break; 293 } 294 if ( !strcmp( buf, "PEAK" ) ) { 295 eNotifyValue= PeakPosition; 296 break; 297 } 298 break; 299 } */ 300 //! ermittelt Einheit des Thetamotors und Winkelwert eines Kanals + setzt den 301 //! Motor , der zu Begin der Funktion gesetzt war 302 303 mlSetAxis( nOldId ); 304 //! o-t-offset init. 305 dOffsetOmega= dOffsetTheta= 0.0; 306 307 //! psd-offset + Messkanalnr. ini. 308 dPsdOffset= 0.0; 309 nMeasurementChannel= 0; 310 311 //! neu akk 312 //! standardmaessig nicht akkumuliert darstellen 313 bAccumulatedDisplay= FALSE; 314 315 ReportUse.bMonitor= ReportUse.bAbsorber= ReportUse.bTime= ReportUse.bIntegral= FALSE; 316 317 // ehemalig extern-Verweise aus A_INTERN.CPP 318 strcpy(DataFile, ""); 319 bAquisitionActive= FALSE; 320 nLinePoints= 100; 321 bSetDXZero= bSetDYZero= bSetRLSave= FALSE; 322 nEnvironment= 0; 323 324 // ehemalig static in A_EXTERN.CPP 325 strcpy(szODF, ""); 326 strcpy(szOWF, ""); 327 strcpy(szTDF, ""); 328 strcpy(szTWF, ""); 329 strcpy(DismantleFile, ""); 330 }; 331 //***************************************************************************** 332 333 void TAreaScanParameters::ResetPosition() { 334 if (GetPsd() != 0) { 335 fPsdRange= GetPsd()->GetAngleRange(); 336 nFirstReadColumn= GetPsd()->GetFirstChannel(); 337 nLastReadColumn= GetPsd()->GetLastChannel(); 338 } else { 339 fPsdRange= 0; 340 nFirstReadColumn= 0; 341 nLastReadColumn= 0; 342 } 343 344 //! Omegamotor und zugehoerige Werte setzen 345 mlSetAxis( nOmega ); 346 dOmegaWidth= mGetValue( Width ); 347 if ( !mGetDistance( dOmegaMin ) ) 348 dOmegaMin= mGetValue(MinDistanceRel); 349 dOmegaMax= min( mGetValue(MaxDistanceRel), dOmegaMin+4.0 ); 350 351 //! Thetamotor und zughoerige Werte setzen 352 mlSetAxis( nTheta ); 353 dThetaWidth= max( mGetValue(MinWidth), mGetValue(Width) ); // 27.07.2004 dMoveRelation * dOmegaWidth 354 if ( !mGetDistance( dThetaMin ) ) 355 dThetaMin= mGetValue(MinDistanceRel); 356 dThetaMin= max( mGetValue(MinDistanceRel), min( mGetValue(MaxDistanceRel), dThetaMin)); // 27.07.2004 dMoveRelation * dOmegaMin 357 dThetaMax= max( mGetValue(MinDistanceRel), min( mGetValue(MaxDistanceRel), dThetaMin+CalcValueInUnit(mlGetUnit(nTheta), fPsdRange))); // 27.07.2004 dMoveRelation * dOmegaMax 358 dThetaWindow= dThetaMax - dThetaMin; 359 d2ThetaStart= dThetaMin; 360 } 361 //***************************************************************************** 362 363 TOneDimDetector* TAreaScanParameters::GetPsd() 364 { 365 if (!Detector) 366 return 0; 367 if (Detector->GetDimension() != 1) 368 return 0; 369 return dynamic_cast<TOneDimDetector*>(Detector); 370 } 371 372 //############################################################################# 373 // TAreaScanWindow 374 //############################################################################# 375 376 //! registr. des ScanFensters und das ScanFensterMenue erstellen 377 //! setzen von weiteren Defaultwerten 378 TAreaScanWindow::TAreaScanWindow( HINSTANCE aInstance ) : TAreaScanParameters(), TPlotWindow(aInstance), ScanReport(0), ScanReport2(0), oldDetector(0) 379 { 380 bInterrupted= FALSE; 381 bCalibrationActive= FALSE; 382 bShowPsdContinuous= FALSE; 383 m_PsdContinousType= PsdUnknown; 384 bSaveContinuous= FALSE; 385 bThetaScanCompleted= FALSE; 386 //! keine DB-Zusammensetzung 387 bComposeDB= FALSE; 388 LowerBound= 0.5; 389 UpperBound= 800.0; 390 WindowType= wtAreaScan; 391 bAreaScanStarted= FALSE; 392 393 //! erstellen der Menüeintraege des Areascanfensters 394 hHoleMenu= LoadMenu(GetMainInstance(), MAKEINTRESOURCE(menu_AreaScan)); 395 // Fix für PopupMenüs aus Ressourcen (Dummy Popup) 396 TheMenu= GetSubMenu(hHoleMenu, 0); 397 398 // Fuer TPlotWindow 399 LowerBound= 0.1f; 400 UpperBound= 10000.0f; 401 bXY_Scaling= TRUE; 402 // pointer to output formats 403 mlSetAxis( nOmega ); 404 strcpy( szODF, mGetDF() ); 405 strcpy( szOWF, mGetSF() ); 406 mlSetAxis( nTheta ); 407 strcpy( szTDF, mGetDF() ); 408 strcpy( szTWF, mGetSF() ); 409 410 ResetPosition(); // ruft auch TAreaScanParameters::ResetPosition() und initialisiert m_MotorUnit und m_DetektorUnit 411 412 //! alt // Reportstruktur fuer Absorber-Position, Omega und ??? 413 //! initial. der Datenbasis + zusatzinfos 414 ScanReport= lpDBase->GetScanReport(); 415 ScanReport2= new TCurve; 416 417 /*lpDBase->New(); 418 nActiveScan= 0; 419 MainCurve= lpDBase->GetCurve( nActiveScan ); 420 421 bOldDataLoaded= FALSE; 422 //! FIX Fehler 39 423 VisualDB.dThetaWindow= dThetaWindow; 424 VisualDB.dMoveRelation= dMoveRelation; 425 VisualDB.dOmegaMin= dOmegaMin; 426 VisualDB.dOmegaMax= dOmegaMax; 427 if ( GetPsd() != 0 ) { 428 VisualDB.bPsd= TRUE; 429 VisualDB.fAngleRange= GetPsd()->GetAngleRange(); 430 VisualDB.fAngleStep= GetPsd()->GetAngleStep(); 431 } else { 432 VisualDB.bPsd= FALSE; 433 VisualDB.fAngleRange= dThetaWindow; 434 VisualDB.fAngleStep= dThetaWindow / dThetaWidth; 435 } 436 VisualDB.dThetaMinFirst= dThetaMin; 437 VisualDB.dThetaMaxFirst= dThetaMin + (dOmegaMax - dOmegaMin) / dOmegaWidth * dOmegaWidth * dMoveRelation;*/ 438 New(); 439 440 VisualDB.dThetaMinLast= dThetaMin + VisualDB.fAngleRange; 441 VisualDB.dThetaMaxLast= VisualDB.dThetaMaxFirst + VisualDB.fAngleRange; 442 443 //! Scanstart ist erlaubt (param. ungueltig) 444 //! FIX Fehler 77 445 bScanSetupOk= FALSE; 446 447 oldDetector= TDetectorManager::DetectorManager().GetDetector(); 448 449 // neu Kullmann, Reinecker 450 bFirstScan= TRUE; 451 bSavedSecondaryCoor = bSecondaryCoor; 452 strcpy(m_RepFileName, ""); 453 }; 454 //***************************************************************************** 455 456 //! loeschen der Datenbasis ,des Menues und speichern von Werten in der Ini-Datei 457 TAreaScanWindow::~TAreaScanWindow() 458 { 459 char buf[ MaxString ]; 460 RECT rc, rcm; 461 462 // Messung/ kont. Spektrenanzeige stoppen (falls aktiv) 463 Interrupt(); 464 465 lpDBase->New(); 466 //! loeschen des Fenstermenue + senden von Detektorsignalen an das 467 //! AreaScanfenster beenden 468 if (Detector != 0) 469 { 470 Detector->MeasureStop(); 471 Detector->SetControlWnd( NULL ); 472 } 473 if (Monitor != 0) 474 { 475 Monitor->MeasureStop(); 476 Monitor->SetControlWnd( NULL ); 477 } 478 479 //! AreaScanfenster-eigenschaften sowie Datenpfad,Messzeit und SaveOnReady in 480 //! Ini-File ablegen 481 GetWindowRect( GetFrameHandle(), &rcm ); 482 GetWindowRect( GetHandle(), &rc ); 483 sprintf( buf, "%d", rc.left - rcm.left - 4 ); 484 WritePrivateProfileString( "AreaScan", "xo", buf, GetCFile() ); 485 sprintf( buf, "%d", rc.top - rcm.top - 42 ); 486 WritePrivateProfileString( "AreaScan", "yo", buf, GetCFile() ); 487 sprintf( buf, "%d", rc.right - rc.left ); 488 WritePrivateProfileString( "AreaScan", "dx", buf, GetCFile() ); 489 sprintf( buf, "%d", rc.bottom - rc.top ); 490 WritePrivateProfileString( "AreaScan", "dy", buf, GetCFile() ); 491 WritePrivateProfileString( "AreaScan", "DataPath", szDataPath, GetCFile() ); 492 sprintf( buf, "%.2f", fMaxTime ); 493 WritePrivateProfileString( "AreaScan", "ExposureTime", buf, GetCFile() ); 494 sprintf( buf, "%d", bSaveOnReady ); 495 // Kanal- oder Winkeldarstellung: zuletzt benutze Darstellungsoption speichern 496 IniWriteBool( GetCFile(), "AreaScan", "ChannelsOnXAxis", bSecondaryCoor ); 497 498 //! Hauptfensterverweis auf AreaScanfenster loeschen + datenbasis loeschen 499 Main.AreaScanWindow= NULL; 500 501 TDetectorManager::DetectorManager().SetDetector(oldDetector); 502 if ( oldDetector ) oldDetector->MeasureStart(); 503 504 _FREEOBJ(ScanReport2); 505 }; 506 //***************************************************************************** 507 508 //! Darstellen des AreaScan-Fenster 509 void TAreaScanWindow::OnCreate() 510 { 511 RECT rc; 512 513 Main.AreaScanWindow= this; 514 515 // HotKey's für F1 516 LoadHotKeys( LoadAccelerators(GetMainInstance(), MAKEINTRESOURCE(ACC_AreaScan)) ); // Accelerator aus Ressourcen laden 517 518 Delay( 2000 ); 519 520 //! einlesen der Fenstereigenschaften, des Datenpfades aus dem 521 //! [AreaScan]-Abschnitt des Ini-Files 522 rc.left= GetPrivateProfileInt( "AreaScan", "xo", 500, GetCFile() ); 523 rc.top= GetPrivateProfileInt( "AreaScan", "yo", 400, GetCFile() ); 524 rc.right= rc.left + GetPrivateProfileInt( "AreaScan", "dx", 170, GetCFile() ); 525 rc.bottom= rc.top + GetPrivateProfileInt( "AreaScan", "dy", 50, GetCFile() ); 526 GetPrivateProfileString( "AreaScan", "DataPath", "c:\\", szDataPath, MaxString, GetCFile() ); 527 if ( szDataPath[ max(0, strlen(szDataPath)-1) ] != '\\' ) 528 strcat( szDataPath, "\\" ); 529 // Kanal- oder Winkeldarstellung: zuletzt benutze Darstellungsoption wiederherstellen 530 bSecondaryCoor = IniReadBool( GetCFile(), "AreaScan", "ChannelsOnXAxis", FALSE ); 531 532 //! setzen der Filter und der Extension 533 strcpy( szFilter, "HRM Standard (*.psd)|*.psd||" ); 534 strcpy( szExtension, "psd" ); 535 536 //! Titelzeile des Fensters bestimmen + 537 //! darstellen des Scanfensters 538 SetTitle(); 539 SetWindowPos( GetHandle(), NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER ); 540 }; 541 //***************************************************************************** 542 543 void TAreaScanWindow::ResetPosition() { 544 TAreaScanParameters::ResetPosition(); 545 546 // umrechnen in Detektoreinheiten 547 m_MotorUnit= mlGetUnit(nTheta); 548 if ( GetPsd() ) m_DetectorUnit= GetPsd()->GetUnit(); 549 else m_DetectorUnit= utNone; 550 } 551 //***************************************************************************** 552 553 void TAreaScanWindow::InitializeAreaScanTask() { 554 char buf[ 101 ]; 555 //klier 03.03.2003 556 char bufPro[MaxString]; 557 char fmt[ MaxString ]; 558 char msg[ 101 ]; 559 560 //! Scan nicht bei kont. Anzeige erlaubt 561 if ( bShowPsdContinuous ) 562 { 563 if ( MessageBox(sth_StopContiniousPsd, szMsgLine208, MBASK) != IDYES ) return; // Spektrenanzeige nicht automatisch stoppen 564 StopSensorContinuous(); // erst kont. Spektrenanzeige stoppen 565 } 566 // Alte Daten sichern bzw. neuen Namen vergeben 567 //! test ob die Anzahl der Erwarteten Scans die max. Kapaz. der Datenbasis 568 //! ueberschreitet 569 if ( ( ( dOmegaMax - dOmegaMin ) / dOmegaWidth ) > lpDBase->GetMaxScanNumber() ) 570 { 571 sprintf( msg, szMsgLine008, lpDBase->GetMaxScanNumber() ); 572 MessageBox( msg, szMsgLine208, MBSTOP ); 573 return; 574 } 575 //! FIX Fehler 44 576 dThetaOffset= 0.0; 577 // Motoren initialisieren 578 mlSetAxis( nOmega ); 579 mSetValue( Speed, 10000.0 ); 580 581 //! wenn omega-relativ abfrage ob relative Null zuruecksetzen 582 if ( eScanType==stOmega2ThetaScan && mIsDistanceRelative() ) { 583 strcpy( msg, szMsgLine007 ); 584 if ( IDYES != MessageBox( msg, szMsgLine208, MBASK ) ) 585 mSetRelativeZero( FALSE, 0.0 ); 586 } 587 mlSetAxis( nTheta ); 588 mSetValue( Speed, 10000.0 ); 589 //! wenn theta-relativ abfrage ob relative Null zuruecksetzen 590 if ( eScanType==stOmega2ThetaScan && mIsDistanceRelative() ) { 591 strcpy( msg, szMsgLine006 ); 592 if ( IDYES != MessageBox( msg, szMsgLine208, MBASK ) ) 593 { 594 mSetRelativeZero( FALSE, 0.0 ); 595 dThetaOffset= 0.0; 596 } 597 else dThetaOffset= 0.0; // 03.06.2003 dThetaOffset= mlGetOffset( nTheta ); VERSUCH Positionsausgabe-Problem bei Scan mit Thetaoffset zu beheben 598 } 599 //! auswahl des Scanstartdialogs 600 switch ( eScanType ) 601 { 602 case stOmega2ThetaScan: 603 if ( GetPsd() == 0) 604 { 605 sprintf( fmt, szMsgLine004, szODF, szODF ); 606 dThetaOffset= 0.0; 607 } 608 else 609 sprintf( fmt, szMsgLine003, szODF, szODF ); 610 break; 611 612 case stStandardScan: 613 if ( GetPsd() == 0) 614 break; 615 sprintf( fmt, szMsgLine005, szODF, szODF ); 616 break; 617 618 default: 619 return; 620 } 621 //! dialog anzeigen 622 sprintf( msg, fmt, dOmegaMin, dOmegaMax ); 623 if ( IDNO == MessageBox( msg, szMsgLine208, MBASK ) ) 624 return; 625 626 //! FIX Fehler 70 627 lpDBase->New(); 628 //! FIX Fehler 32 629 if ( bSaveOnReady || bSaveContinuous) 630 SaveFile( atNewName ); 631 632 //klier 03.03.2003 633 if (MessageBox( szMsgLine032, szMessage, MBASK ) == IDYES) 634 { 635 SetProtocolDiffractometryOn(); 636 SetMeasurementProtocolParameter(); 637 if (bSaveContinuous || bSaveOnReady) 638 SetProtocolDiffractometryMessdatei(FileName); 639 SetProtocolDiffractometryNutzer(MeasurementParameter.GetUser()); 640 SetProtocolDiffractometryScanart("AreaScan"); 641 SetProtocolDiffractometryScanmethode("StepScan"); 642 if (dThetaMin != dThetaMax) 643 SetProtocolDiffractometryScantyp("Omega2Theta"); 644 else 645 SetProtocolDiffractometryScantyp("Omega"); 646 SetProtocolDiffractometryScanachse1("Omega"); 647 SetProtocolDiffractometryScanachse2("Theta"); 648 649 SetProtocolDiffractometryDetektor(Detector->GetCharacteristic()); 650 // SetProtocolDiffractometryDetektor(Detector->GetDimension()); 651 652 if ( GetPsd() != 0) 653 { 654 SetProtocolDiffractometryWinkelbereich( GetPsd()->GetAngleRange() ); 655 SetProtocolDiffractometryKanalabstand( GetPsd()->GetAngleStep() ); 656 // SetProtocolDiffractometryMesskanal( GetPsd()->GetWidth() ); 657 // SetProtocolDiffractometryAddiere( GetPsd()->GetAddedChannels() ); 658 SetProtocolDiffractometryMesskanal( nMeasurementChannel ); 659 SetProtocolDiffractometryAddiere( nAddedChannels ); 660 } 661 if (Monitor != 0) 662 SetProtocolDiffractometryMonitor(Monitor->GetCharacteristic()); 663 else 664 SetProtocolDiffractometryMonitor("-"); 665 SetProtocolDiffractometryMesszeit(fMaxTime); 666 SetProtocolDiffractometryImpulse(dwMaxCounts); 667 668 sprintf(bufPro, szODF, dOmegaMin); 669 SetProtocolDiffractometryMinimum1(bufPro); 670 sprintf(bufPro, szOWF, dOmegaWidth); 671 SetProtocolDiffractometrySchrittweite1(bufPro); 672 sprintf(bufPro, szODF, dOmegaMax); 673 SetProtocolDiffractometryMaximum1(bufPro); 674 sprintf(bufPro, szODF, d2ThetaStart); 675 SetProtocolDiffractometryMinimum2(bufPro); 676 if (dThetaMin != dThetaMax) 677 { 678 sprintf(bufPro, szODF, dMoveRelation*dOmegaMax + d2ThetaStart); 679 SetProtocolDiffractometryMaximum2(bufPro); 680 sprintf(bufPro, szOWF, dMoveRelation*dOmegaWidth); 681 SetProtocolDiffractometrySchrittweite2(bufPro); 682 } 683 else 684 { 685 sprintf(bufPro, szODF, d2ThetaStart); 686 SetProtocolDiffractometryMaximum2(bufPro); 687 SetProtocolDiffractometrySchrittweite2(""); 688 } 689 690 ViewOnProtocolDiffractometryDlg(); 691 } 692 else 693 SetProtocolDiffractometryOff(); 694 695 // Sensoren initialisieren 696 //JP wird von Steering.Reset als ersten Schritt getan 697 //Detector->MeasureStop(); 698 bAreaScanStarted= FALSE; // für Steering.Reset() abschalten 699 Steering.Reset(); 700 bAreaScanStarted= TRUE; // nach Steering.Reset() wieder einschalten 701 Steering.StartUp( GetHandle(), nOmega, Detector ); 702 //! Werte an Detektor 703 Detector->SetControlWnd( GetHandle() ); 704 Detector->SetExposureSettings( TExposureSettings(fMaxTime, dwMaxCounts) ); 705 Detector->SetParameters(); 706 707 //! Monitordetektor initialisieren wenn als zusatzinfo gewollt 708 if (Monitor != 0) 709 { 710 if ( Monitor == Detector ) 711 { 712 sprintf( buf, szMsgLine002, Detector->GetCharacteristic() ); 713 MessageBox( buf, szMsgFailure, MBSTOP ); 714 return; 715 } 716 Monitor->MeasureStop(); 717 Monitor->SetControlWnd( GetHandle() ); 718 Monitor->SetExposureSettings( TExposureSettings(fMaxTime * 0.8, dwMaxCounts) ); 719 } 720 721 // ******* Alte Daten verwerfen ********************************************* 722 bFirstScan= TRUE; 723 //! Darstellungsoptionen fuer Scan setzen 724 Steering.Visualising( FALSE, FALSE ); //Fortschritt in Statuszeile ausgeben 725 //! einstellen psd-spez. werte 726 switch ( eScanType ) 727 { 728 case stOmega2ThetaScan: 729 if ( GetPsd() != 0 ) 730 { 731 //! art der Kurvenaktualisierung einstellen 732 GetPsd()->SetSignalGrowUp( bAccumulatedDisplay ); //! neu akk 733 //! einstellen der Anzahl der zusammenzufassenden Kanaele 734 GetPsd()->SetAddedChannels( nAddedChannels ); 735 //! winkelbereich eines Spektrums ermitteln bei psd 736 fPsdRange= GetPsd()->GetAngleRange(); 737 738 //! winkelbereich eines Spektrums ermitteln bei 0-dim. Det. 739 //! Anweisungen sind doppelt 740 GetPsd()->SetSignalGrowUp( bAccumulatedDisplay ); //! neu akk 741 GetPsd()->SetAddedChannels( nAddedChannels ); 742 strcpy( buf, "" ); 743 //! Scan starten 744 Steering.StartCmdExecution( Scan, ForAreaScan, stOmega2ThetaScan, buf, GetHandle() ); 745 } else { 746 fPsdRange= dThetaWindow; 747 bThetaScanCompleted= FALSE; 748 mlSetAxis( nTheta ); 749 //! mSetRelativeZero( TRUE, mGetValue( Distance ) ); 750 mlSetAxis( nOmega ); 751 //! mSetRelativeZero( TRUE, mGetValue( Distance ) ); 752 strcpy( buf, "" ); 753 //! Scan starten 754 Steering.StartCmdExecution( AreaScan, stOmega2ThetaScan, 0, buf, GetHandle() ); 755 } 756 break; 757 758 case stStandardScan: 759 if ( GetPsd() == 0 ) 760 { 761 SetInfo( szMsgLine025 ); 762 return; 763 } 764 //! art der Kurvenaktualisierung einstellen 765 GetPsd()->SetSignalGrowUp( bAccumulatedDisplay ); //! neu akk 766 //! einstellen der Anzahl der zusammenzufassenden Kanaele 767 GetPsd()->SetAddedChannels( nAddedChannels ); 768 //! winkelbereich eines Spektrums ermitteln bei Psd 769 fPsdRange= GetPsd()->GetAngleRange(); 770 GetPsd()->SetSignalGrowUp( bAccumulatedDisplay ); //! neu akk 771 GetPsd()->SetAddedChannels( nAddedChannels ); 772 strcpy( buf, "" ); 773 //! Scan starten 774 Steering.StartCmdExecution( Scan, ForAreaScan, stStandardScan, buf, GetHandle() ); 775 break; 776 } 777 //! akt.Kurve loeschen + AreaScan als aktiv kennzeichnen 778 MainCurve->New(); 779 bMeasurementActive= TRUE; 780 } 781 //***************************************************************************** 782 783 void TAreaScanWindow::DoDataAquisition() { 784 TModalDlg *dlg= 0; 785 if ( bAquisitionActive ) 786 { 787 int hFile; //! FILE * hFile; 788 char buf[ MaxString ]; 789 int cnt, env, row, column; 790 float Odelta, Tdelta, x, y, z, offset, value; 791 double yDelta, xDelta, Omega, Theta, rlxDelta, rlyDelta; 792 TCurve *Scan; 793 bAquisitionActive= FALSE; 794 OFSTRUCT of; 795 796 SetRanges(); 797 798 //! Punkte ausserhalb des Koordinatensystems nicht zulassen 799 if ( mPoint1.x > AltCoorSys.xMax || mPoint2.x > AltCoorSys.xMax || 800 mPoint1.y > AltCoorSys.yMax || mPoint2.y > AltCoorSys.yMax || 801 mPoint1.x < AltCoorSys.xMin || mPoint2.x < AltCoorSys.xMin || 802 mPoint1.y < AltCoorSys.yMin || mPoint2.y < AltCoorSys.yMin ) 803 { 804 MessageBox(szMsgLine200, szMsgFailure, MBINFO ); 805 return; 806 } 807 //! Beruecksichtigen, ob Gerade horizontal oder vertikal und nicht frei Hand... 808 if (bSetDYZero) 809 mPoint2.y= mPoint1.y; 810 if (bSetDXZero) 811 mPoint2.x= mPoint1.x; 812 813 yDelta= (mPoint2.y - mPoint1.y) / nLinePoints; 814 xDelta= (mPoint2.x - mPoint1.x) / nLinePoints; 815 816 //! wenn Abstand der Messpunkte nicht gross genug... 817 if ((fabs(yDelta) < 1e-7) && (fabs(xDelta) < 1e-7)) 818 { 819 MessageBox(szMsgLine201, szMsgFailure, MBINFO ); 820 return; 821 } 822 823 //*** Point0 and Point1 are valid 824 //! TData Struktur speichert errechnete Werte... 825 TData *lpData= (TData*) new TData[nLinePoints]; 826 //! Berechnung der Punkte der Gerade je nach Darstellungstyp 827 switch (eOutputType) 828 { 829 case otReciprokeLatticeBitmap: 830 lpData[0].dX= mPoint1.x; 831 lpData[0].dY= mPoint1.y; 832 lpData[nLinePoints - 1].dX= mPoint2.x; 833 lpData[nLinePoints - 1].dY= mPoint2.y; 834 lpData[0].fDelta= lpData[0].fIntensity= 0.0; 835 lpData[nLinePoints - 1].fDelta= lpData[nLinePoints - 1].fIntensity= 0.0; 836 837 //! Zeile und Spalte im Bitmap berechnen 838 row= (mPoint1.y - AltCoorSys.yMin) / AltCoorSys.ySF; 839 column= (mPoint1.x - AltCoorSys.xMin) / AltCoorSys.xSF; 840 841 //! Omega und Theta aus dem "Daten"Feld holen - Theta ist ohne Offset gespeichert 842 if ( BSource->IsDatenInited() ) 843 { 844 lpData[0].dOmega= BSource->GetOmega(row, column); 845 lpData[0].dTheta= BSource->GetTheta(row, column); 846 } else { 847 lpData[0].dOmega= 0; 848 lpData[0].dTheta= 0; 849 } 850 lpData[0].dX= mPoint1.x; 851 lpData[0].dY= mPoint1.y; 852 853 //! Zeile und Spalte im Bitmap berechnen 854 row= (mPoint2.y - AltCoorSys.yMin) / AltCoorSys.ySF; 855 column= (mPoint2.x - AltCoorSys.xMin) / AltCoorSys.xSF; 856 857 //! Omega und Theta aus dem "Daten"Feld holen - Theta ist ohne Offset gespeichert 858 if ( BSource->IsDatenInited() ) 859 { 860 lpData[nLinePoints - 1].dOmega= BSource->GetOmega(row, column); 861 lpData[nLinePoints - 1].dTheta= BSource->GetTheta(row, column); 862 } 863 else 864 { 865 lpData[nLinePoints - 1].dOmega= 0; 866 lpData[nLinePoints - 1].dTheta= 0; 867 } 868 869 lpData[nLinePoints - 1].dX= mPoint2.x; 870 lpData[nLinePoints - 1].dY= mPoint2.y; 871 872 //! nLinePoints gibt an, wieviele Messpunkte auf der Gerade liegen sollen... 873 yDelta= (lpData[nLinePoints - 1].dOmega - lpData[0].dOmega) / nLinePoints; 874 xDelta= (lpData[nLinePoints - 1].dTheta - lpData[0].dTheta) / nLinePoints; 875 rlxDelta= (lpData[nLinePoints - 1].dX - lpData[0].dX) / nLinePoints; 876 rlyDelta= (lpData[nLinePoints - 1].dY - lpData[0].dY) / nLinePoints; 877 878 for (cnt= 0; cnt<nLinePoints-1; cnt++) 879 { 880 lpData[cnt + 1].fDelta= lpData[cnt + 1].fIntensity= 0.0; 881 lpData[cnt + 1].dOmega= lpData[cnt].dOmega + yDelta; 882 lpData[cnt + 1].dTheta= lpData[cnt].dTheta + xDelta; 883 lpData[cnt + 1].dX= lpData[cnt].dX + rlxDelta; 884 lpData[cnt + 1].dY= lpData[cnt].dY + rlyDelta; 885 } 886 break; 887 888 case otMatrixBitmap: 889 //! nLinePoints gibt an, wieviele Messpunkte auf der Gerade liegen sollen... 890 lpData[0].dTheta= mPoint1.x; 891 lpData[0].dOmega= mPoint1.y; 892 lpData[0].fDelta= lpData[0].fIntensity= 0.0; 893 for (cnt= 1; cnt<nLinePoints; cnt++) 894 { 895 lpData[cnt].fDelta= lpData[cnt].fIntensity= 0.0; 896 lpData[cnt].dOmega= lpData[cnt - 1].dOmega + yDelta; 897 lpData[cnt].dTheta= lpData[cnt - 1].dTheta + xDelta; 898 } 899 break; 900 } // switch (eOutputType) 901 902 903 //*** search the related intensities 904 //! berechnen der fehlenden Einheiten 905 switch (eOutputType) 906 { 907 case otReciprokeLatticeBitmap: 908 for (cnt= 0;cnt < nLinePoints;cnt++) 909 { 910 Omega= lpData[cnt].dOmega; 911 Theta= lpData[cnt].dTheta; 912 row= ScanReport->GetValueByValue(Omega, Odelta, offset); 913 //** reverse connection between psd and theta-axis 914 //! Omega-=Odelta; 915 Scan= lpDBase->GetCurve(row); 916 917 //** pick out the intensity 918 column= Scan->GetValueByValue(Theta, Tdelta, value); 919 920 //! Theta-Offset beruecksichtigen 921 if (VisualDB.bPsd) 922 lpData[cnt].dTheta= Theta + GetThetaOffset(row); 923 else 924 lpData[cnt].dTheta= Theta + GetThetaOffset(row) - VisualDB.dThetaMinFirst; 925 926 //! Theta-=Tdelta; 927 //! lpData[cnt].fIntensity=value; 928 value= 0; 929 //! nEnvironment liegt immer zwischen 0-3 930 env= nEnvironment; 931 //! beruecksichtigen der gewuenschten Umgebungsmesspunkte, 932 //! damit eventuelle krasse Intensitaetsunterschiede wegfallen 933 //! berechne Intensitaet 934 if (Tdelta > Odelta) 935 while (env + 1) 936 { 937 Scan->SetPP(column + env); 938 Scan->PGet(x, y, z); 939 value += y; 940 Scan->SetPP(column - env); 941 Scan->PGet(x, y, z); 942 value += y; 943 env--; 944 } 945 else 946 while (env + 1) 947 { 948 Scan= lpDBase->GetCurve(row + env); 949 Scan->SetPP(column); 950 Scan->PGet(x, y, z); 951 value += y; 952 Scan= lpDBase->GetCurve(row - env); 953 Scan->SetPP(column); 954 Scan->PGet(x, y, z); 955 value += y; 956 env--; 957 } 958 //! bilde arithmetisches Mittel der Intensitaeten 959 lpData[cnt].fIntensity= value / ((nEnvironment + 1) * 2); 960 //! quadriere Deltas, damit sich pos./neg. Werte nicht gegenseitig aufheben 961 lpData[cnt].fDelta= sqrt(pow(Odelta, 2) + pow(Tdelta, 2)); 962 } 963 break; 964 965 case otMatrixBitmap: 966 for (cnt= 0;cnt < nLinePoints;cnt++) 967 { 968 Omega= lpData[cnt].dOmega; 969 row= ScanReport->GetValueByValue(Omega, Odelta, offset); 970 Theta= lpData[cnt].dTheta; 971 972 if (VisualDB.bPsd) 973 { 974 //! Theta-Offset beruecksichtigen 975 Theta= lpData[cnt].dTheta - (GetThetaOffset(row) - VisualDB.dThetaMinFirst); 976 Theta -= AltCoorSys.xMin; 977 } 978 979 Scan= lpDBase->GetCurve(row); 980 //! Omega-=Odelta; 981 //** pick out the intensity 982 column= Scan->GetValueByValue(Theta, Tdelta, value); 983 //! Theta-=Tdelta; 984 //! Omega und Theta in RL Koordinaten umrechnen 985 Omega= DegToRad(Omega); 986 Theta= DegToRad(lpData[cnt].dTheta); 987 lpData[cnt].dX= ArToRLx(Omega, Theta) * (M_PI / (0.5* 988 MeasurementParameter.GetWaveLength())); 989 lpData[cnt].dY= ArToRLy(Omega, Theta) * (M_PI / (0.5* 990 MeasurementParameter.GetWaveLength())); 991 //! lpData[cnt].fIntensity=value; 992 value= 0; 993 //! nEnvironment liegt immer zwischen 0-3 994 env= nEnvironment; 995 //! beruecksichtigen der gewuenschten Umgebungsmesspunkte, 996 //! damit eventuelle krasse Intensitaetsunterschiede wegfallen 997 //! berechne Intensitaet 998 if (xDelta > yDelta) 999 while (env + 1) 1000 { 1001 Scan->SetPP(column + env); 1002 Scan->PGet(x, y, z); 1003 value += y; 1004 Scan->SetPP(column - env); 1005 Scan->PGet(x, y, z); 1006 value += y; 1007 env--; 1008 } 1009 else 1010 while (env + 1) 1011 { 1012 Scan= lpDBase->GetCurve(row + env); 1013 Scan->SetPP(column); 1014 Scan->PGet(x, y, z); 1015 value += y; 1016 Scan= lpDBase->GetCurve(row - env); 1017 Scan->SetPP(column); 1018 Scan->PGet(x, y, z); 1019 value += y; 1020 env--; 1021 } 1022 //! bilde arithmetisches Mittel der Intensitaeten 1023 lpData[cnt].fIntensity= value / ((nEnvironment + 1) * 2); 1024 //! quadriere Deltas, damit sich pos./neg. Werte nicht gegenseitig aufheben 1025 lpData[cnt].fDelta= sqrt(pow(Odelta, 2) + pow(Tdelta, 2)); 1026 } 1027 break; 1028 } // switch 1029 1030 //! Daten speichern 1031 hFile= OpenFile( DataFile, &of, OF_CREATE ); //! hFile=fopen(DataFile,"w"); 1032 if ( hFile == HFILE_ERROR ) 1033 { 1034 MessageBox(szMsgLine204, szMessage, MBINFO ); 1035 _FREELIST(lpData); 1036 return; 1037 } 1038 //! ergaenzt um Header und Data Info 1039 _lwrite(hFile, szMsgLine202, strlen(szMsgLine202)); //! fwrite( buf,strlen(buf),1,hFile); 1040 //! FileType mit eingefuehrt - TScanWindow.eSaveFormat=dtnFile (beim Einlesen) 1041 sprintf( buf, "FileType=Aquisition\n", FileName ); 1042 _lwrite(hFile, buf, strlen(buf)); //! fwrite( buf,strlen( buf ), 1,hFile ); 1043 sprintf( buf, "Source= %s\n", FileName ); 1044 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile ); 1045 1046 //! Abfrage RL oder normale Koordinaten speichern 1047 if (!bSetRLSave) 1048 { 1049 sprintf( buf, "Omega Intens. Theta RLY RLX Delta\n", FileName ); 1050 _lwrite(hFile, buf, strlen(buf)); //! fwrite( buf,strlen(buf),1,hFile ); 1051 1052 _lwrite(hFile, szMsgLine205, strlen(szMsgLine205)); //! fwrite(buf,strlen(buf),1,hFile); 1053 1054 sprintf(buf, "[Data]\n", FileName); 1055 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile); 1056 1057 //! Unterscheidung eingebaut, damit Omega aufsteigend abgespeichert 1058 if (lpData[0].dOmega < lpData[nLinePoints - 1].dOmega) 1059 for (cnt= 0;cnt < nLinePoints;cnt++) 1060 { 1061 sprintf( buf, "%.8f\t %.8f\t %.8f\t %.8f\t %.8f\t %.8f", 1062 lpData[cnt].dOmega, lpData[cnt].fIntensity, lpData[cnt].dTheta, lpData[cnt].dY, lpData[cnt].dX, lpData[cnt].fDelta ); 1063 strcat(buf, EOL); 1064 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile ); 1065 } 1066 else 1067 for (cnt= nLinePoints - 1;cnt >= 0;cnt--) 1068 { 1069 sprintf( buf, "%.8f\t %.8f\t %.8f\t %.8f\t %.8f\t %.8f", 1070 lpData[cnt].dOmega, lpData[cnt].fIntensity, lpData[cnt].dTheta, lpData[cnt].dY, lpData[cnt].dX, lpData[cnt].fDelta); 1071 strcat(buf, EOL); 1072 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile); 1073 } 1074 } 1075 else 1076 { // bSetRLSave==TRUE 1077 sprintf(buf, "RLY Intens. RLX Omega Theta Delta\n", FileName); 1078 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile); 1079 _lwrite(hFile, szMsgLine203, strlen(szMsgLine203)); //! fwrite(buf,strlen(buf),1,hFile); 1080 1081 sprintf(buf, "[Data]\n", FileName); 1082 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile); 1083 1084 //! Unterscheidung eingebaut, damit RLY aufsteigend abgespeichert 1085 if (lpData[0].dY < lpData[nLinePoints - 1].dY) 1086 for (cnt= 0;cnt < nLinePoints;cnt++) 1087 { 1088 sprintf( buf, "%.8f\t %.8f\t %.8f\t %.8f\t %.8f\t %.8f", 1089 lpData[cnt].dY, lpData[cnt].fIntensity, lpData[cnt].dX, lpData[cnt].dOmega, lpData[cnt].dTheta, lpData[cnt].fDelta ); 1090 strcat(buf, EOL); 1091 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile ); 1092 } 1093 else 1094 for (cnt= nLinePoints - 1;cnt >= 0;cnt--) 1095 { 1096 sprintf( buf, "%.8f\t %.8f\t %.8f\t %.8f\t %.8f\t %.8f", 1097 lpData[cnt].dY, lpData[cnt].fIntensity, lpData[cnt].dX, lpData[cnt].dOmega, lpData[cnt].dTheta, lpData[cnt].fDelta); 1098 strcat(buf, EOL); 1099 _lwrite(hFile, buf, strlen(buf)); //! fwrite(buf,strlen(buf),1,hFile ); 1100 } 1101 } 1102 _lclose(hFile); 1103 _FREELIST(lpData); 1104 1105 char *buf2= new char[ strlen(szMsgLine206)+strlen(DataFile)+1 ]; 1106 sprintf(buf2, szMsgLine206, DataFile); 1107 MessageBox( buf2, szMsgLine207, MBINFO ); 1108 _FREELIST(buf2); 1109 return; 1110 } 1111 dlg= new TAquisitionDlg(this); 1112 if ( dlg ) dlg->ExecuteDialog( GetHandle() ); 1113 _FREEOBJ(dlg); 1114 UpdateWnd(); 1115 } 1116 1117 LRESULT TAreaScanWindow::OnEvent ( HWND aHandle, UINT message, WPARAM wParam, LPARAM lParam ) { 1118 switch ( message ) { 1119 case cm_UpdateRanges: 1120 SetRanges(); 1121 UpdateWnd(); 1122 return 01; 1123 1124 default: 1125 return TPlotWindow::OnEvent( aHandle, message, wParam, lParam ); 1126 } 1127 } 1128 1129 //! behandeln der Windowsbotschaften 1130 LRESULT TAreaScanWindow::OnCommand(WPARAM wParam, LPARAM lParam) 1131 { 1132 TModalDlg *dlg= 0; 1133 WPARAM Cmd= GET_WM_COMMAND_ID(wParam, lParam); 1134 switch (Cmd) 1135 { 1136 case cm_New: // Hauptmenü 1137 StopSensorContinuous(); 1138 Steering.Reset(); 1139 bAreaScanStarted= FALSE; // für Steering.Reset() abschalten 1140 bInterrupted= FALSE; 1141 SetFileName(""); 1142 ResetPosition(); 1143 New(); // das alles darf nicht in New() verschoben werden = NUR HIER wenn Menüpunkt geklickt wurde 1144 return 0l; 1145 1146 //! aufruf der Dialogbox 'Einstellungen AreaScan' 1147 case cm_SetupAreaScan: 1148 //! FIX Fehler 74 1149 if ( !mlIsAxisValid( Omega ) || ((!mlIsAxisValid(Theta) && ! TDetectorManager::DetectorManager().DimAvailable(1))) ) 1150 { 1151 MessageBox(szMsgLine021, szMsgFailure, MBINFO); 1152 return 01; 1153 } 1154 dlg= ( TSetupAreaScanDlg* ) new TSetupAreaScanDlg( this ); // in dlg_if.cpp 1155 if ( dlg ) dlg->ExecuteDialog( GetHandle() ); 1156 _FREEOBJ(dlg); 1157 //! Scanstart ist erlaubt (param. gueltig) 1158 //! FIX Fehler 77 1159 bScanSetupOk= TRUE; 1160 UpdateWnd(); 1161 return 01; // behandelt 1162 1163 case cm_InitializeAreaScan: // AreaScan starten 1164 InitializeAreaScanTask(); 1165 return 01; // Botschaft behandelt 1166 1167 //! Aufruf durch Menue "Data Aquisition"/"Daten Erhebung" 1168 //! Benutzer zieht Gerade ueber ein Bitmap und es werden alle 1169 //! Punkte (Anzahl der Punkte vom Nutzer einstellbar) der Gerade berechnet 1170 //! Es werden berechnet Theta,Omega,RLX,RLY,Intensitaet,Delta 1171 //! Delta gibt die gemittelte Abweichung des berechneten Koordinatenpaars 1172 //! von einem tatsaechlich vorhandenen Messkoordinatenpaar an 1173 case cm_DataAquisition: 1174 DoDataAquisition(); 1175 return 01; 1176 1177 //! 'Choose Scan' 1178 //! aufruf der Dialogbox zur Auswahl der scans 1179 case cm_ChooseScan: 1180 //! FIX Fehler 46 1181 if (bShowPsdContinuous) 1182 { 1183 MessageBox(szMsgLine017, szMessage, MBINFO); 1184 return 0l; 1185 } 1186 //! keine Datenbasis im speicher 1187 if ( 2 > lpDBase->GetCNumber() ) 1188 { 1189 MessageBox(szMsgLine031, szMessage, MBINFO); 1190 return 0l; 1191 } 1192 //! neu Kullmann+Reinecker: TheModeless ersetzt durch ChooseScanDlg 1193 if ( (!ChooseScanDlg) || (!ChooseScanDlg->GetHandle()) ) 1194 { // !GetHandle() ist wichtig für den Fall, dass sich das Dialogfenster selbst zerstört hat !!! 1195 ChooseScanDlg= ( TChooseScanDlg* ) new TChooseScanDlg( this, &ChooseScanDlg ); 1196 if ( ChooseScanDlg ) 1197 ChooseScanDlg->Initialize( GetMainInstance(), GetFrameHandle() ); 1198 } 1199 else 1200 _FREEOBJ(ChooseScanDlg); 1201 return 0l; 1202 1203 //! Aufruf Dialog DB-Zusammensetzung 1204 case cm_ComposeDB: 1205 ComposeDB(); 1206 return 0l; 1207 1208 //! Aufruf Dialog DB-Zerlegung 1209 case cm_DismantleDB: 1210 DismantleDB(); 1211 return 0l; 1212 1213 // Aufruf Dialog 'PSD-Kalibrierung' 1214 case cm_CalibratePsd: 1215 CalibratePsd(); 1216 return 0l; 1217 1218 //! 'Show Energy-Spectrum' 1219 //! kont. Anzeige des Energiespektrums aktivieren 1220 case cm_ShowPsdE_Data: 1221 ShowSensorContinuous( PsdEnergyData ); 1222 return 0l; 1223 1224 //! 'Show Position-Spectrum' 1225 //! kont. Anzeige des Positionsspektrums aktivieren 1226 case cm_ShowPsdP_Data: 1227 ShowSensorContinuous( PsdPositionData ); 1228 return 0l; 1229 1230 //! 'Settings...' 1231 //! aufruf der Psd-Einstellungsbox 1232 case cm_SetupPsd: 1233 if ( ( Detector != 0 ) && ( Detector->HasSpecificParametersDlg() == TRUE ) ) Detector->RunSpecificParametersDlg( GetHandle() ); 1234 return 01; 1235 1236 case cm_Help: 1237 WinHelp(GetHandle(), GetHelpFile(), HELP_CONTEXT, Help_AreaScan); 1238 return 0l; // Botschaft verarbeitet 1239 1240 default: 1241 return TPlotWindow::OnCommand(wParam, lParam); 1242 } 1243 } 1244 //***************************************************************************** 1245 // Mausbedienung 1246 //***************************************************************************** 1247 1248 void TAreaScanWindow::OnPopupMenuInit(WPARAM, LPARAM lParam) 1249 { 1250 //! sperren von Psd-spezifischen Menuepunkten wenn kein Psd angeschlossen ist 1251 if ( ! TDetectorManager::DetectorManager().DimAvailable(1) ) 1252 { 1253 EnableMenuItem( TheMenu, cm_ShowPsdE_Data, MF_GRAYED ); 1254 EnableMenuItem( TheMenu, cm_SetupPsd, MF_GRAYED ); 1255 EnableMenuItem( TheMenu, cm_CalibratePsd, MF_GRAYED ); 1256 EnableMenuItem( TheMenu, cm_ShowPsdP_Data, MF_GRAYED ); 1257 } 1258 1259 //! DB-Zerlegung nur zugelassen, wenn DB im Speicher 1260 if ( lpDBase->GetCNumber() < 2 ) 1261 EnableMenuItem( TheMenu, cm_DismantleDB, MF_GRAYED ); 1262 else 1263 EnableMenuItem( TheMenu, cm_DismantleDB, MF_ENABLED ); 1264 //! sperren von 'Start AreaScan' wenn bereits ein Scan laeuft der nicht unterbrochen wurde 1265 if ( ( bAreaScanStarted && !bInterrupted ) || !bScanSetupOk ) 1266 EnableMenuItem( TheMenu, cm_InitializeAreaScan, MF_GRAYED ); 1267 else 1268 EnableMenuItem( TheMenu, cm_InitializeAreaScan, MF_ENABLED ); // Scan muss initialisiert worden sein 1269 1270 //! sperren von 'Choose Scan' wenn irgendeine nichtmodale Dialogbox aktiv ist 1271 //! neu Kullmann+Reinecker: TheModeless ersetzt durch ChooseScanDlg 1272 if ( (ChooseScanDlg) && (ChooseScanDlg->GetHandle()) ) 1273 EnableMenuItem( TheMenu, cm_ChooseScan, MF_GRAYED ); // !GetHandle() ist wichtig für den Fall, dass sich das Dialogfenster selbst zerstört hat !!! 1274 else 1275 EnableMenuItem( TheMenu, cm_ChooseScan, MF_ENABLED ); 1276 1277 //! sperren von 'Settings...' wenn kein Psd verfuegbar ist 1278 if ( ( Detector == 0 ) || ( Detector->GetDimension() != 1) ) 1279 EnableMenuItem( TheMenu, cm_SetupPsd, MF_GRAYED ); 1280 else 1281 EnableMenuItem( TheMenu, cm_SetupPsd, MF_ENABLED ); 1282 //! sperren von 'Fixing' wenn Darstellungsart ungleich Kurve + sperren von 1283 //! 'Inquire Data' wenn Darstellungsart gleich Kurve 1284 switch ( eOutputType ) { 1285 case otReciprokeLatticeBitmap: 1286 case otMatrixBitmap: 1287 EnableMenuItem( TheMenu, cm_FreezeCurve, MF_GRAYED ); 1288 EnableMenuItem( TheMenu, cm_DataAquisition, MF_ENABLED ); 1289 break; 1290 1291 default: 1292 EnableMenuItem( TheMenu, cm_DataAquisition, MF_GRAYED ); 1293 //! neu fixscan 1294 if (1 > SecondCurve->GetPNumber()) 1295 { 1296 EnableMenuItem( TheMenu, cm_FreezeCurve, MF_ENABLED ); 1297 EnableMenuItem( TheMenu, cm_SaveSecondCurve, MF_GRAYED ); 1298 EnableMenuItem( TheMenu, cm_KillSecondCurve, MF_GRAYED ); 1299 //! dieser Befehl macht bei Win31 probleme 1300 //! ModifyMenu( TheMenu, 8, MF_STRING|MF_BYPOSITION,8,"Scan" ); 1301 } 1302 else 1303 { 1304 //! ModifyMenu( TheMenu, 8, MF_STRING|MF_BYPOSITION,8,"fixierten Scan" ); 1305 EnableMenuItem( TheMenu, cm_FreezeCurve, MF_GRAYED ); 1306 EnableMenuItem( TheMenu, cm_SaveSecondCurve, MF_ENABLED ); 1307 EnableMenuItem( TheMenu, cm_KillSecondCurve, MF_ENABLED ); 1308 } 1309 } 1310 }; 1311 //***************************************************************************** 1312 1313 //! aufruf wenn linke Maustaste losgelassen wurde(d.h. Endpunkt erreicht) 1314 //! wird in 2 Faellen aktiv 1315 //! - messen der Entfernung zwischen zwei Punkten ueber TPlotWindow 1316 //! - bei Dataaquisition (DataaquisitionActive==true) zusaetzlich Kommando senden 1317 void TAreaScanWindow::OnLButtonUp( WPARAM wParam, LPARAM lParam ) 1318 { 1319 TPlotWindow::OnLButtonUp( wParam, lParam ); 1320 if ( DataaquisitionActive ) 1321 { 1322 DataaquisitionActive= false; 1323 PostMessage( GetHandle(), WM_COMMAND, cm_DataAquisition, 0l ); 1324 } 1325 }; 1326 //***************************************************************************** 1327 1328 //! aufruf wenn linke Maustaste gedrueckt wurde(d.h Startpunkt wurde gewaehlt) 1329 //! wird in 2 Faellen aktiv 1330 //! - messen der Entfernung zwischen zwei Punkten (!DataaquisitionActive) 1331 //! - bei Dataaquisition (DataaquisitionActive==true) 1332 void TAreaScanWindow::OnLButtonDown( WPARAM wParam, LPARAM lParam ) 1333 { 1334 if ( bAquisitionActive ) 1335 DataaquisitionActive= true; 1336 else 1337 DataaquisitionActive= false; 1338 TPlotWindow::OnLButtonDown( wParam, lParam ); 1339 }; 1340 //***************************************************************************** 1341 1342 //! loescht aktuelle datenbasis + baut AreaScanfenster neu auf 1343 //! Rueckkehrcode immer True 1344 BOOL TAreaScanWindow::New( void ) 1345 { 1346 lpDBase->New(); 1347 nActiveScan= 0; 1348 MainCurve= lpDBase->GetCurve( nActiveScan ); 1349 1350 bOldDataLoaded= FALSE; 1351 1352 //! FIX Fehler 39 1353 VisualDB.bPsd= ( GetPsd() != 0 ); 1354 VisualDB.dThetaWindow= dThetaWindow; 1355 VisualDB.dMoveRelation= dMoveRelation; 1356 VisualDB.dOmegaMin= dOmegaMin; 1357 VisualDB.dOmegaMax= dOmegaMax; 1358 if ( GetPsd()!=0 ) 1359 { 1360 VisualDB.fAngleRange= GetPsd()->GetAngleRange(); 1361 VisualDB.fAngleStep= GetPsd()->GetAngleStep(); 1362 } 1363 else 1364 { 1365 VisualDB.fAngleRange= dThetaWindow; 1366 VisualDB.fAngleStep= dThetaWindow / dThetaWidth; 1367 } 1368 VisualDB.dThetaMinFirst= dThetaMin; 1369 VisualDB.dThetaMaxLast= VisualDB.dThetaMinLast + VisualDB.fAngleRange; 1370 VisualDB.dThetaMaxFirst= dThetaMin + VisualDB.fAngleRange; 1371 if (eScanType == stStandardScan) 1372 VisualDB.dThetaMinLast= dThetaMin; 1373 else 1374 VisualDB.dThetaMinLast= dThetaMin + (dOmegaMax - dOmegaMin) / dOmegaWidth * dOmegaWidth * dMoveRelation; 1375 1376 ScanReport2->New(); 1377 return TPlotWindow::New(); 1378 }; 1379 //***************************************************************************** 1380 1381 //! setzt Titel des AreaScanFensters 1382 //! Rueckkehrcode immer True 1383 BOOL TAreaScanWindow::SetTitle() 1384 { 1385 strcpy( m_Title, szTitle ); 1386 //! haengt "<untitled.psd>" bei neuer Datei , sonst FileName an 1387 //! und schreibt ihn ins Fenster 1388 if ( bIsNewFile ) 1389 strcat( m_Title, "<untitled.psd>" ); 1390 else 1391 strcat( m_Title, FileName ); 1392 return TMDIWindow::SetTitle(); 1393 }; 1394 //***************************************************************************** 1395 1396 //! zeichnet in abhaengigkeit des eingestellten Darstellungstyps das AreaScan- 1397 //! fenster neu 1398 void TAreaScanWindow::UpdateWnd( EPaintType act ) 1399 { 1400 switch ( eOutputType ) 1401 { 1402 case otReciprokeLatticeBitmap: 1403 BSource->UpdateBitmapSource(); 1404 break; 1405 1406 case otMatrixBitmap: 1407 BSource->UpdateBitmapSource(); 1408 break; 1409 } 1410 //! behandelt Darstellungstyp Curve 1411 TMDIWindow::UpdateWnd( act ); 1412 }; 1413 //***************************************************************************** 1414 1415 //! setzt die Achsen-min. und -max. abhaengig von der Darstellungsart 1416 void TAreaScanWindow::SetRanges( void ) 1417 { 1418 float xshift; 1419 float fRangeSec= 1.0; 1420 TDisplay DParam; 1421 // spezielle Darstellung ist aktiv oder Datei wurde geladen: Detektor- und Motoreinstellungen nicht ändern! 1422 bool bUnchangeData= (bShowPsdContinuous || bMeasurementActive || bOldDataLoaded); 1423 1424 // Kanalbereich aktualisieren 1425 if ( !bUnchangeData ) 1426 if ( GetPsd() ) { 1427 fPsdRange= GetPsd()->GetAngleRange(); 1428 nFirstReadColumn= GetPsd()->GetFirstChannel(); 1429 nLastReadColumn= GetPsd()->GetLastChannel(); 1430 } else { 1431 fPsdRange= 0; 1432 nFirstReadColumn= 0; 1433 nLastReadColumn= 0; 1434 } 1435 1436 //! Datenbasis spez. Darstellung 1437 DParam.bPsd= VisualDB.bPsd; 1438 DParam.dThetaWindow= VisualDB.dThetaWindow; 1439 DParam.dMoveRelation= VisualDB.dMoveRelation; 1440 DParam.dOmegaMin= VisualDB.dOmegaMin; 1441 DParam.dOmegaMax= VisualDB.dOmegaMax; 1442 1443 // spezielle Darstellung ist aktiv oder Datei wurde geladen 1444 if ( bUnchangeData ) { 1445 DParam.bPsd= ( GetPsd() != 0 ); 1446 DParam.dThetaWindow= dThetaWindow; 1447 DParam.dMoveRelation= dMoveRelation; 1448 DParam.dOmegaMin= dOmegaMin; 1449 DParam.dOmegaMax= dOmegaMax; 1450 } 1451 1452 // Kanalbereich aktualisieren 1453 if ( bUnchangeData && GetPsd() ) { 1454 DParam.fAngleRange= GetPsd()->GetAngleRange(); 1455 DParam.fAngleStep= GetPsd()->GetAngleStep(); 1456 fRangeSec= GetPsd()->GetAngleRange() / DParam.fAngleRange; 1457 } else { 1458 DParam.fAngleRange= VisualDB.fAngleRange; 1459 DParam.fAngleStep= VisualDB.fAngleStep; 1460 fRangeSec= CalcValueInUnit(utSekunden, (nLastReadColumn-nFirstReadColumn+1)/*GetChannelNumber() nimmt die Kanaleinstellung vom PSD, kann hier also nicht verwendet werden*/ * DParam.fAngleStep) / DParam.fAngleRange; // Kullmann, Reinecker 1461 } 1462 1463 // neu, Thetapositionen haben immer gefehlt 1464 DParam.dThetaMinFirst= DParam.dThetaMinLast= dThetaMin; 1465 DParam.dThetaMaxFirst= DParam.dThetaMaxLast= dThetaMin+CalcValueInUnit(m_MotorUnit, DParam.fAngleRange); 1466 DParam.dThetaWindow= DParam.dThetaMaxFirst-DParam.dThetaMinFirst; 1467 1468 switch ( eOutputType ) 1469 { 1470 case otReciprokeLatticeBitmap: //! RL-Bitmap 1471 CoorSys.zMax= UpperBound; 1472 CoorSys.zMin= LowerBound; 1473 // The AltCoorSys is now used and will be setted in 1474 // TransformDBaseToBitmap() 1475 break; 1476 1477 case otMatrixBitmap://! RAW-Matrix 1478 CoorSys.zMax= UpperBound; 1479 CoorSys.zMin= LowerBound; 1480 CoorSys.yMin= DParam.dOmegaMin; 1481 CoorSys.yMax= DParam.dOmegaMax; 1482 1483 //! setzen der x-Achse in Abhängigkeit von Kurvenpunktzahl 1484 if ( MainCurve->GetPNumber() < 7 ) 1485 { 1486 CoorSys.xMin= DParam.dOmegaMin * DParam.dMoveRelation; 1487 CoorSys.xMax= CoorSys.xMin + DParam.fAngleRange; 1488 /*GetPsd()->GetAngleRange();*/ 1489 break; 1490 } 1491 xshift= GetThetaOffset( 0 ); 1492 CoorSys.xMin= MainCurve->GetMin( P_X ) + xshift; 1493 //! dies muss mit rein! B.Buss 1494 xshift= GetThetaOffset(lpDBase->GetCNumber() - 1); 1495 CoorSys.xMax= MainCurve->GetMax( P_X ) + xshift; 1496 break; 1497 1498 case otCurve://! Kurve 1499 CoorSys.yMin= LowerBound; 1500 CoorSys.yMax= UpperBound; 1501 if ( !DParam.bPsd ) 1502 { 1503 //! wenn kein Psd dann test ob Punkte in Kurve 1504 if ( MainCurve->GetPNumber() < 1 ) 1505 { 1506 //! wenn nicht x-Achse( -xx/2 -> xx/2) 1507 CoorSys.xMin= - DParam.dThetaWindow / 2.0; 1508 CoorSys.xMax= DParam.dThetaWindow / 2.0; 1509 break; 1510 } 1511 1512 //! sonst x-Achse (min: auf min.Winkelwert der Kurve -> max: min + xx) 1513 CoorSys.xMin= MainCurve->GetMin( P_X ); 1514 CoorSys.xMax= CoorSys.xMin + DParam.dThetaWindow; 1515 break; 1516 } 1517 //! Psd angeschlossen 1518 if ( MainCurve->GetPNumber() < 2 ) 1519 { 1520 //! kurve hat keine Punkte 1521 if ( bSecondaryCoor ) //! Kanaldarstellung 1522 { 1523 CoorSys.xMin= 0.0; 1524 CoorSys.xMax= DParam.fAngleRange / DParam.fAngleStep * fRangeSec; 1525 /*! GetPsd()->GetAngleRange( Sekunden ) / 1526 GetPsd()->GetAngleStep();*/ 1527 } else { //! Winkeldarstellung 1528 CoorSys.xMin= DParam.dThetaMinFirst; // 27.07.2004 DParam.dOmegaMin * DParam.dMoveRelation; 1529 CoorSys.xMax= DParam.dThetaMaxFirst; // 27.07.2004 CoorSys.xMin + DParam.fAngleRange 1530 /*GetPsd()->GetAngleRange();*/ 1531 } 1532 break; 1533 } 1534 //! Kurve hat Punkte 1535 if ( bSecondaryCoor ) // Kanaldarst. 1536 { 1537 CoorSys.xMin= MainCurve->GetMin( P_Z ); 1538 CoorSys.xMax= MainCurve->GetMax( P_Z ); 1539 } else { // Winkeldarst. 1540 //! liefert 0 wenn kein Psd ansonsten den ThetaOffset und setzt 1541 //! entsprechend die x-Achse 1542 xshift= GetThetaOffset( 0 ); 1543 CoorSys.xMin= MainCurve->GetMin( P_X ) + xshift; 1544 CoorSys.xMax= MainCurve->GetMax( P_X ) + xshift; 1545 } 1546 break; 1547 1548 default: 1549 MessageBox( szMsgLine023, szMessage, MBINFO ); 1550 break; 1551 } 1552 }; 1553 1554 //***************************************************************************** 1555 //Schnittstellen fuer Ablaufsteuerung 1556 //***************************************************************************** 1557 1558 double TAreaScanWindow::GetActAngle( const LPCSTR aName, BOOL &aValid ) const 1559 { 1560 int Index = -1; 1561 aValid= FALSE; 1562 TMotor *Mtr = 0; 1563 1564 for (UINT i= 0; i < lpMList->GetAxisNumber(); i++) 1565 { 1566 if ( (strcmp( aName, lpMList->MP(i)->pCharacteristic()) == 0) ) 1567 { 1568 Mtr= lpMList->MP( i ); 1569 break; 1570 } 1571 } 1572 if (!Mtr) return 0.0; // nicht gefunden 1573 1574 if (Mtr->IsMoveFinish()) 1575 aValid= Mtr->GetAngle( 1 ); // mGetDistance 1576 else 1577 aValid= Mtr->GetAngle( 0 ); // mGetDistanceProcess 1578 return Mtr->GetAngle(); // aValid == TRUE <--> Position erfolgreich ausgelesen und umgerechnet 1579 }; 1580 //***************************************************************************** 1581 1582 //! behandelt eigentlichen Scanablauf sowie die kont. Anzeige, Calibrate ... 1583 //! Aufruf durch cm_CounterSet 1584 void TAreaScanWindow::CounterSetRequest( LPARAM lParam ) 1585 { 1586 float absorber, channel, psdtheta, peakpos; 1587 //! FIX Fehler 30 1588 float x, y, x2, y2, z2, intens, integral, time; 1589 //! FIX Fehler 47 1590 char buf[ 3 * MaxString ], fmt[ 3 * MaxString ], msg[ MaxString ]; 1591 double dTheta, dOmega; 1592 static float fMonitorSignal; 1593 int nNumOffs= 0; 1594 BOOL bValid= false; 1595 1596 //! bei kont. Anzeige 1597 if ( bShowPsdContinuous ) 1598 { 1599 if ( m_PsdContinousType==PsdEnergyData ) strcpy( msg, szMsgLine026e ); 1600 else if ( m_PsdContinousType==PsdPositionData ) strcpy( msg, szMsgLine026p ); 1601 else strcpy( msg, szMsgLine026 ); 1602 //! Kurvenspektrum+ integrale Intensitaet von Psd holen 1603 GetPsd()->FillInCurve( *MainCurve, mlGetUnit(nTheta) ); 1604 GetPsd()->GetIntegral( integral ); 1605 //! wenn keine Calibr. dann Messung neu starten 1606 //! (sonst wird dies in TCalibr. gemacht) 1607 if ( !bCalibrationActive && Detector->IsDataValid() ) 1608 Detector->MeasureStart(); 1609 dTheta = GetActAngle( "Theta", bValid ); 1610 dOmega = GetActAngle( "Omega", bValid ); 1611 //>>TK 1612 sprintf( fmt, "%s O:%s T:%s Peak( %s | %s) Integr.Intensity: %s", msg, "%.4f", "%.4f", szTDF, "%.2f", "%.2f"); 1613 //! in abhaengigkeit von x-achsen-art(Kanal,Winkel) statuszeilen ausgabe 1614 if ( bSecondaryCoor ) //! Kanaldarst. 1615 { 1616 channel= GetPsd()->GetMaximumChannel(); 1617 intens= GetPsd()->GetMaximumIntensity(); 1618 sprintf( buf, fmt, dOmega, dTheta, channel, intens, integral); 1619 } else { //! Winkeldarst. 1620 MainCurve->GetGravityCenter( psdtheta, intens, channel ); 1621 psdtheta += GetThetaOffset( 0 ); 1622 sprintf( buf, fmt, dOmega, dTheta, psdtheta, intens, integral); 1623 } 1624 SetInfo( buf ); 1625 UpdateWnd(); 1626 return; 1627 } 1628 //! bei unterbrochenem Scan + Scan nicht aktiviert abbruch 1629 if ( bInterrupted ) 1630 return; 1631 if ( !bMeasurementActive ) 1632 return; 1633 //! ab hier ablauf bei laufendem AreaScan 1634 //! Monitorintensitaet ermitteln und merken (in static-var.) bis 1635 //! Messdetektor auch fertig ist 1636 if ( ( Monitor != 0 ) && ( lParam == Monitor->GetId() ) ) 1637 { 1638 Monitor->GetIntegral( fMonitorSignal ); 1639 return; 1640 } 1641 1642 bFileChanged= TRUE; 1643 //! position der motoren holen + bei theta offset dazurechnen 1644 dOmega= mlGetValue( nOmega, Distance ); 1645 dTheta= mlGetValue( nTheta, Distance ); 1646 //! o-t-offset in reale Motorpositionen einrechnen 1647 x= ( float ) (dOmega + dOffsetOmega); 1648 // Theta will be stored in absolute Koordinates 1649 y= ( float ) (dTheta + dOffsetTheta - dThetaOffset); 1650 1651 //*************************************************************************** 1652 //**** Datenbasis aktualisieren ********************************************* 1653 //*************************************************************************** 1654 //! erste Messung(erstes Spektrum wird nicht benutzt) weil Datenbasis schon 1655 1656 //! mit einer Kurve init. wurde 1657 if ( bFirstScan ) 1658 nNumOffs= ( Detector->IsDataValid() ) ? 0 : 0; 1659 else 1660 nNumOffs= ( Detector->IsDataValid() ) ? 0 : 1; 1661 switch ( eScanType ) 1662 { 1663 case stOmega2ThetaScan://! Omega2Thetascan 1664 //########################################################### 1665 //! Scan mit Psd 1666 if ( GetPsd() != 0 ) 1667 { 1668 //! wenn Detektordaten gueltig 1669 //! wenn nicht 1.Spektrum in Datenbasis neues Spektrum hinzufuegen 1670 //! Spektrum + integr. vom detektor holen 1671 MainCurve= lpDBase->GetLastCurve(); 1672 GetPsd()->FillInCurve( *MainCurve, mlGetUnit(nTheta) ); 1673 GetPsd()->GetIntegral( integral ); 1674 if ( GetPsd()->IsDataValid() ) 1675 { 1676 bFileChanged= TRUE; 1677 //! neues Spektrum in datei speichern bei kont. Speichern 1678 if ( bSaveContinuous ) 1679 UpdateFile(); 1680 //! nur wenn Messzeit abgelaufen kurve in Datenbasis 1681 //! speichern und Datenbasis vergroessern 1682 lpDBase->AddCurve(); // 10.04.2004 Parameterübergabe nicht mehr notwendig MainCurve->GetPNumber() 1683 nActiveScan= lpDBase->GetCNumber() - 1; 1684 } 1685 //! Kurve + integrale Int. vom Detektor holen + Kurve in Datenbasis 1686 //! Thetawinkel der Peakpos. holen*/ 1687 //! absorberposition ermitteln 1688 if (ReportUse.bAbsorber ) 1689 absorber= mlGetValue( mlGetIdByName( Absorber ), Distance ); 1690 else 1691 absorber= GetPsd()->GetMaximumChannel(); 1692 1693 MainCurve->GetGravityCenter( psdtheta, intens, peakpos ); 1694 psdtheta += y; 1695 //! in abhaengigkeit von der eingestellten Reportart zum Spektrum die 1696 //! omega- , Thetapos. sowie den jeweiligen Reportwert im Scanreport 1697 //! speichern ueberfluessig (wahrscheinlich als Erweiterung geplant) 1698 if ( Detector->IsDataValid() ) 1699 { 1700 time= Detector->GetRealTime(); 1701 //! monitordet. reset 1702 if ( Monitor != 0 ) 1703 Monitor->MeasureStop(); 1704 else 1705 fMonitorSignal= 0.0; 1706 //! Zusatzinfos anlegen 1707 ScanReport->PAdd( x, y, integral); 1708 ScanReport2->PAdd( time, fMonitorSignal, absorber); 1709 //! naechste pos. anfahren 1710 Steering.DetectorRequest(); 1711 } 1712 1713 //########################################################### 1714 //! Scan mit 0-dim. Detektor 1715 } 1716 else 1717 { // GetPsd() == 0 1718 //! im ersten schritt keine neue Kurve in Datenbasis 1719 if ( bFirstScan ) 1720 bFirstScan= FALSE; 1721 //! wenn 0-dim. detektor ueber gesamten Thetabereich gelaufen dann 1722 //! eine neue Kurve in Datenbasis 1723 else if ( bThetaScanCompleted ) 1724 { 1725 bThetaScanCompleted= FALSE; 1726 //! bei kont. speichern akt. maincurve an datei anhaengen 1727 //! FIX Fehler 34 1728 if ( bSaveContinuous ) 1729 UpdateFile(); 1730 // save data about last scan 1731 //! FIX Fehler 30,40 1732 MainCurve->SetPP(); 1733 MainCurve->PGet(x2, y2, z2); 1734 //! neu info 1735 //!MainCurve->GetGravityCenter(intens,intens,peakpos,2); 1736 ScanReport->PAdd(z2, x2, intens= 0); 1737 lpDBase->AddCurve( ); // 10.04.2004 Parameterübergabe nicht mehr notwendig MainCurve->GetPNumber() 1738 MainCurve= lpDBase->GetLastCurve(); 1739 nActiveScan= lpDBase->GetCNumber() - 1; 1740 } 1741 //! intens.wert vom Detektor holen + an Kurve anhaengen 1742 Detector->GetIntegral( intens ); 1743 //! FIX Fehler 30,40 1744 MainCurve->PAdd( y, intens, x ); 1745 bFileChanged= TRUE; 1746 1747 //! naechste pos. anfahren 1748 Steering.DetectorRequest(); 1749 } 1750 break; 1751 1752 //####################################################################### 1753 case stStandardScan: 1754 //! standardscan nur mit Psd erlaubt 1755 if ( GetPsd() == 0 ) 1756 return; 1757 //! wenn Detektordaten gueltig 1758 //! wenn nicht 1.Spektrum in Datenbasis neues Spektrum hinzufuegen 1759 //! Spektrum + integr. vom detektor holen 1760 MainCurve= lpDBase->GetLastCurve(); 1761 GetPsd()->FillInCurve( *MainCurve, mlGetUnit(nTheta) ); 1762 GetPsd()->GetIntegral( integral ); 1763 if ( GetPsd()->IsDataValid() ) 1764 { 1765 bFileChanged= TRUE; 1766 //! neues Spektrum in datei speichern bei kont. Speichern 1767 if ( bSaveContinuous ) 1768 UpdateFile(); 1769 //! nur wenn Messzeit abgelaufen kurve in Datenbasis 1770 //! speichern und Datenbasis vergroessern 1771 lpDBase->AddCurve( ); // 10.04.2004 Parameterübergabe nicht mehr notwendig MainCurve->GetPNumber() 1772 nActiveScan= lpDBase->GetCNumber() - 1; 1773 } 1774 //! Kurve + integrale Int. vom Detektor holen + Kurve in Datenbasis 1775 //! absorberposition ermitteln 1776 if ( ReportUse.bAbsorber ) 1777 absorber= mlGetValue( mlGetIdByName( Absorber ), Distance ); 1778 else 1779 absorber= GetPsd()->GetMaximumChannel(); 1780 1781 //! Thetawinkel der Peakpos. holen 1782 MainCurve->GetGravityCenter( psdtheta, intens, peakpos ); 1783 psdtheta += y; 1784 //! in abhaengigkeit von der eingestellten Reportart zum Spektrum die 1785 //! omega- , Thetapos. sowie den jeweiligen Reportwert im Scanreport 1786 //! speichern ueberfluessig (wahrscheinlich als Erweiterung geplant) 1787 if ( Detector->IsDataValid() ) 1788 { 1789 //! neu info 1790 //! monitordet. reset 1791 if ( Monitor != 0 ) 1792 Monitor->MeasureStop(); 1793 else 1794 fMonitorSignal= 0.0; 1795 time= Detector->GetRealTime(); 1796 //! zusatzinfos anlegen 1797 ScanReport->PAdd(x, y, integral); 1798 ScanReport2->PAdd(time, fMonitorSignal, absorber); 1799 1800 //! naechste pos. anfahren 1801 Steering.DetectorRequest(); 1802 } 1803 break; 1804 } // switch ( eScanType ) 1805 1806 //*************************************************************************** 1807 //**** Anzeige fuer Signalaufbau aktualisieren ****************************** 1808 //*************************************************************************** 1809 //! UpdateWindow: 1810 switch ( eScanType ) 1811 { 1812 case stOmega2ThetaScan: 1813 //! Anzeige bei 0-dim.Det. 1814 if ( GetPsd() == 0 ) 1815 { 1816 //! string fuer Statusleiste erstellen 1817 sprintf( fmt, szMsgLine001, szODF, szTDF ); 1818 1819 sprintf( buf, fmt, x, y, intens ); 1820 1821 //! wenn akt. Kurve keine Punkte dann Fenster neuzeichnen sonst den 1822 //! neuen Punkt der Kurve einzeichnen 1823 if ( 1 == MainCurve->GetPNumber() ) 1824 UpdateWnd(); 1825 else 1826 UpdateWnd( ptPaintPoint ); 1827 1828 //! Anzeige bei Psd 1829 } 1830 else 1831 { 1832 //! string fuer Statusleiste erstellen 1833 #ifdef GermanVersion 1834 sprintf( fmt, "Messung laeuft! O:%s T:%s", szODF, szTDF ); 1835 sprintf( buf, "%s P(%s<>%%.1f) Gesamt-Intensitaet:%%.1f > %%d", fmt, szTDF );
1836 #else 1837 sprintf( fmt, "Measurement ! O:%s T:%s", szODF, szTDF ); 1838 sprintf( buf, "%s P(%s<>%%.1f) Integral Intensity:%%.lf > %%d", fmt, szTDF );
1839 #endif 1840 strcpy( fmt, buf ); 1841 nNumOffs += lpDBase->GetCNumber() - 1; 1842 if ( bSecondaryCoor ) 1843 sprintf( buf, fmt, x, y, peakpos, intens, integral, nNumOffs ); 1844 else 1845 sprintf( buf, fmt, x, y, psdtheta, intens, integral, nNumOffs ); 1846 //! neue Kurve zeichnen 1847 UpdateWnd(); 1848 //! wenn integr. Int. zu hoch dann Overflow ausgeben 1849 if ( GetPsd()->IsSoftOverflow() ) 1850 strcat( buf, " > 'OverflowIntensity' !" ); 1851 } 1852 break; 1853 1854 case stStandardScan: 1855 //! nur fuer Psd erlaubt 1856 if ( GetPsd() == 0 ) 1857 return; 1858 //! string fuer Statusleiste erstellen 1859 sprintf( fmt, szMsgLine009, szODF ); 1860 sprintf( buf, szMsgLine010, fmt, szTDF ); 1861 strcpy( fmt, buf ); 1862 nNumOffs += lpDBase->GetCNumber() - 1; 1863 if ( bSecondaryCoor ) 1864 sprintf( buf, fmt, x, peakpos, intens, integral, nNumOffs ); 1865 else 1866 sprintf( buf, fmt, x, psdtheta, intens, integral, nNumOffs ); 1867 //! neue Kurve zeichnen 1868 UpdateWnd(); 1869 //! wenn integr. Int. zu hoch dann Overflow ausgeben 1870 if ( GetPsd()->IsSoftOverflow() ) 1871 strcat( buf, " Overflow !" ); 1872 break; 1873 } // switch ( eScanType ) 1874 //! String in Statusleiste schreiben 1875 SetInfo( buf ); 1876 }; 1877 //***************************************************************************** 1878 1879 //! wird augerufen nachdem AreaScan abgeschlossen wurde 1880 //! aus m_main.cpp bei cm_SteeringReady 1881 void TAreaScanWindow::SteeringReady( LPARAM lParam ) 1882 { 1883 if ( !bAreaScanStarted ) return; 1884 char buf[ MaxString ]; 1885 1886 // Funktion behandelt Meldung cm_CmdExecuted 1887 bAreaScanStarted= FALSE; 1888 bMeasurementActive= FALSE; 1889 Detector->MeasureStop(); 1890 // Scan wurde ausgefuehrt 1891 switch ( HIWORD( lParam ) ) 1892 { 1893 case R_Failure: 1894 //klier 16.08.02 1895 SetProtocolDiffractometryOff(); 1896 1897 sprintf( buf, szMsgLine020, LOWORD( lParam ) ); 1898 MessageBox( buf, szMsgFailure, MBINFO ); 1899 break; 1900 1901 default://! keine Fehler aufgetreten 1902 //! neu akk 1903 //! letztes Spektrum bei Scan mit Psd wieder loeschen 1904 //! es wird immer eins zuviel angelegt 1905 if ( GetPsd() != 0 ) 1906 lpDBase->DelCurve(); 1907 //! Info in Statusleiste 1908 sprintf( buf, szMsgLine011, lpDBase->GetCNumber() ); 1909 SetInfo( buf ); 1910 //! FIX Fehler 30,40 1911 if ( (eScanType == stOmega2ThetaScan) && (GetPsd() == 0) ) 1912 { 1913 //! die Werte zu der letzten Scankurve in Report- 1914 //! kurve ablegen 1915 //! FIX Fehler 30,40 1916 float x2, y2, z2, intens /*,peakpos*/; 1917 MainCurve->SetPP(); 1918 MainCurve->PGet(x2, y2, z2); 1919 ScanReport->PAdd(z2, x2, intens= 0); 1920 bFileChanged= TRUE; 1921 //! letztes Spektrum in datei speichern bei kont. Speichern 1922 if ( bSaveContinuous ) 1923 UpdateFile(); 1924 } 1925 //! wenn savecont. ausgewaehlt dann Headerinfo aktualisieren + Scanreport 1926 if ( bSaveContinuous ) 1927 { // Header aktualisieren 1928 SaveMeasurementInfo( TRUE ); 1929 SaveReport(); 1930 } 1931 //! FIX Fehler 76 1932 if ( bSaveOnReady ) 1933 { 1934 if ( SaveFile( atNoAsk ) ) 1935 sprintf( buf, szMsgLine012 ); 1936 else 1937 sprintf( buf, szMsgLine019 ); 1938 //! FIX Fehler 76 1939 } 1940 else if ( bSaveContinuous ) 1941 sprintf( buf, szMsgLine012 ); 1942 else 1943 sprintf( buf, szMsgLine018 ); 1944 MessageBox( buf, szMessage, MBINFO ); 1945 1946 //klier 01.03.2003 1947 if (IsProtocolDiffractometryOn()) 1948 { 1949 if (!bSaveContinuous && !bSaveOnReady) 1950 { 1951 SetMeasurementProtocolParameter(); 1952 SaveProtocolDiffractometryParameter(); 1953 } 1954 ViewOnProtocolDiffractometryDlg(); 1955 SetProtocolDiffractometryReadOnly(); 1956 SetProtocolDiffractometryOff(); 1957 } 1958 } // switch ( HIWORD(lParam) ) 1959 //! Detektor stoppen 1960 Detector->MeasureStop(); 1961 Detector->PopSettings(); 1962 Detector->SetControlWnd( NULL ); 1963 }; 1964 //----------------------------------------------------------------------------- 1965 1966 //! wird augerufen nachdem AreaScan abgeschlossen wurde 1967 //! aus m_main.cpp bei cm_SteeringReset 1968 void TAreaScanWindow::SteeringReset( LPARAM lParam ) 1969 { 1970 if ( !bAreaScanStarted ) return; 1971 1972 // Funktion behandelt Meldung cm_CmdExecuted 1973 bAreaScanStarted= FALSE; 1974 bMeasurementActive= FALSE; 1975 if ( Detector ) Detector->MeasureStop(); 1976 SetInfo(szMsgLine222); 1977 } 1978 //***************************************************************************** 1979 1980 //! Fkt. wird bei unterbrechen/fortsetzen eines AreaScans aufgerufen oder zum 1981 //! ausschalten einer kont. Anzeige 1982 void TAreaScanWindow::Interrupt() 1983 { 1984 //! kont. Anzeige ausschalten wenn aktiv 1985 if ( bShowPsdContinuous ) 1986 { 1987 StopSensorContinuous(); 1988 return; 1989 } 1990 1991 if ( !bAreaScanStarted ) return; 1992 1993 //! Hauptmenueeintrag aendern und bInterrupted negieren 1994 TMDIWindow::Interrupt(); 1995 if ( bInterrupted ) { //! Messung unterbrechen (wenn Messung nicht läuft, müssen wir auch eine andere Makroverarbeitung abbrechen können - wenn gerade unser Fenster geöffnet ist) 1996 //! Messung unterbrechen + in Statusleiste anzeigen 1997 Steering.ToggleInterrupt(); 1998 SetInfo( szMsgLine013 ); 1999 } else { // Messung weiterfueren 2000 Steering.ToggleInterrupt(); 2001 } 2002 }; 2003 //***************************************************************************** 2004 2005 //! aufruf zur PsdCalibrierung 2006 //! FIX Fehler 35 2007 void TAreaScanWindow::CalibratePsd( void ) 2008 { 2009 BOOL bsCoor; 2010 2011 //! nur wenn Thetamotor und Psd verfuegbar 2012 if ( !mlIsAxisValid( Theta ) || !TDetectorManager::DetectorManager().DimAvailable(1) ) 2013 { 2014 MessageBox( szMsgLine021, szMsgFailure, MBINFO ); 2015 return; 2016 } 2017 if ( bShowPsdContinuous ) 2018 { 2019 if ( MessageBox(szMsgLine312, szMsgLine213, MBASK) != IDYES ) return; // Spektrenanzeige nicht automatisch stoppen 2020 StopSensorContinuous(); // erst kont. Spektrenanzeige stoppen 2021 } 2022 2023 2024 bCalibrationActive= TRUE; 2025 int sChann= 0; 2026 if ( GetPsd() ) sChann= GetPsd()->GetAddedChannels(); 2027 bsCoor= bSecondaryCoor; 2028 StartSensorContinuous(PsdPositionData, TRUE); 2029 2030 //! Calibrierungsdialogbox 2031 TDetectorGUI::RunPsdCalibrateDialog(GetHandle(), *MainCurve); 2032 2033 StopSensorContinuous(); 2034 bSecondaryCoor= bsCoor; 2035 bCalibrationActive= FALSE; 2036 if ( GetPsd() && sChann ) GetPsd()->SetAddedChannels(sChann); 2037 2038 Detector->MeasureStart(); 2039 UpdateWnd(); 2040 }; 2041 2042 //***************************************************************************** 2043 // kont. Spektrenanzeige 2044 //***************************************************************************** 2045 2046 void TAreaScanWindow::StartSensorContinuous( EPsdDataType type, BOOL CalibrateSpecial ) { 2047 2048 if ( bShowPsdContinuous || type==PsdUnknown ) return; // ist schon gestartet oder unbekannte Spektrenart 2049 2050 //! kont. Anzeige NUR bei Kurvendarst. erlaubt 2051 if ( eOutputType != otCurve ) 2052 { 2053 MessageBox( szMsgLine027, szMsgLine209, MBSTOP ); 2054 return; 2055 } 2056 2057 //! kont. Anzeige nur fuer Psd erlaubt 2058 if ( !TDetectorManager::DetectorManager().DimAvailable(1) || !GetPsd() ) 2059 { 2060 MessageBox( szMsgLine024, szMessage, MBINFO ); 2061 return; 2062 } 2063 2064 TDetectorManager::DetectorManager().SetDetector( 0, 1 ); 2065 SetDetector( TDetectorManager::DetectorManager().GetDetector() ); 2066 Detector->MeasureStop(); 2067 2068 bShowPsdContinuous= TRUE; // ist gestartet 2069 m_PsdContinousType= type; 2070 2071 //! FIX Fehler 46 2072 TCurve *dummy= new TCurve; 2073 MainCurve= dummy; 2074 2075 // Eingeschraenkte Aufloesung einstellen 2076 GetPsd()->SetSignalGrowUp( FALSE ); 2077 Detector->SetControlWnd( GetHandle() ); 2078 2079 //! Anzeigeart an Psd uebergeben 2080 if ( type==PsdEnergyData || type==PsdPositionData ) 2081 GetPsd()->SetDataType( type ); 2082 2083 if ( type==PsdEnergyData ) { 2084 bSavedSecondaryCoor = bSecondaryCoor; // aktuelle Darstellung merken 2085 bSecondaryCoor= TRUE; // immer Kanaldarstellung 2086 } 2087 2088 // im Menue kennzeichnen 2089 CheckMenuItem( TheMenu, cm_ShowPsdE_Data, ( type == PsdEnergyData ) ? MF_CHECKED : MF_UNCHECKED ); 2090 CheckMenuItem( TheMenu, cm_ShowPsdP_Data, ( type == PsdPositionData ) ? MF_CHECKED : MF_UNCHECKED ); 2091 Detector->MeasureStart(); 2092 } 2093 //***************************************************************************** 2094 2095 void TAreaScanWindow::StopSensorContinuous() { 2096 if ( !bShowPsdContinuous || m_PsdContinousType==PsdUnknown ) return; // ist schon gestoppt oder unbekannte Spektrenart 2097 2098 TDetectorManager::DetectorManager().SetDetector( 0, 1 ); 2099 SetDetector( TDetectorManager::DetectorManager().GetDetector() ); 2100 Detector->MeasureStop(); 2101 2102 bShowPsdContinuous= FALSE; // ist gestoppt 2103 2104 //! FIX Fehler 46 2105 _FREEOBJ(MainCurve); // zuerst den alten <dummy> wieder freigeben 2106 MainCurve= lpDBase->GetCurve(nActiveScan); 2107 2108 //! alte Werte in Psd zuruecksetzen und im Menue Kennzeichnung entfernen 2109 // Kullmann, Reinecker Detector->PopSettings(); 2110 Detector->SetControlWnd( NULL ); 2111 Detector->MeasureStart(); 2112 //TPlotWindow::bSecondaryCoor= FALSE; 2113 UpdateWnd(); 2114 2115 if ( m_PsdContinousType==PsdEnergyData ) 2116 { 2117 CheckMenuItem( TheMenu, cm_ShowPsdE_Data, MF_UNCHECKED ); 2118 GetPsd()->SetDataType( PsdPositionData ); 2119 bSecondaryCoor = bSavedSecondaryCoor; // gemerkte Beschriftung wieder herstellen 2120 } 2121 else if ( m_PsdContinousType==PsdPositionData ) 2122 CheckMenuItem( TheMenu, cm_ShowPsdP_Data, MF_UNCHECKED ); 2123 } 2124 //***************************************************************************** 2125 2126 //! diese Fkt. schaltet die kont. Spektrumsanzeige fuer Psd an oder aus 2127 void TAreaScanWindow::ShowSensorContinuous( EPsdDataType type ) { 2128 if ( bShowPsdContinuous ) { // Spektrenanzeige der Art <datatype> ist gerade aktiv: diese stoppen 2129 StopSensorContinuous(); // aktuelle stoppen 2130 if ( type!=m_PsdContinousType ) StartSensorContinuous(type); // neue Art Starten 2131 } else { // Anzeige ist aus: neue Einschalten 2132 StartSensorContinuous(type); 2133 } 2134 }; 2135 //***************************************************************************** 2136 2137 void TAreaScanWindow::GetTitleX(int i, int titlesx, char *buf, bool reduceLines) { 2138 if ( bShowPsdContinuous && m_PsdContinousType==PsdEnergyData ) { // Energiespektrum aktiv 2139 // Klasseneinteilung der Intensitäten 2140 TPlotWindow::GetTitleX(i, titlesx, buf, reduceLines); 2141 2142 // letzte Beschriftung = Beschriftung der Abzissen-Achse 2143 if ( i==tilesx ) 2144 sprintf(buf, szEnergy ); // "Kanaele" 2145 } else { 2146 // Zahlenwerte 2147 TPlotWindow::GetTitleX(i, titlesx, buf, reduceLines); 2148 2149 // letzte Beschriftung = Beschriftung der Abzissen-Achse 2150 if ( i==tilesx ) { 2151 char unit[_MAXLENUNIT+1]; 2152 if ( Detector && Detector->GetDimension()==1 ) strcpy(unit, dynamic_cast<TOneDimDetector*>(Detector)->GetUnitName()); 2153 else strcpy(unit, ""); 2154 if ( eOutputType==otReciprokeLatticeBitmap ) 2155 sprintf(buf, "qx"); 2156 else if ( bSecondaryCoor ) 2157 sprintf(buf, szChannel, mlGetAxisName(nTheta)); 2158 else if ( strlen(unit)==0 ) { 2159 sprintf(buf, szAngle, mlGetAxisName(nTheta)); 2160 } 2161 else { 2162 if ( reduceLines ) sprintf(buf, szAngleUnitEZ, mlGetAxisName(nTheta)); 2163 else sprintf(buf, szAngleUnit, mlGetAxisName(nTheta), unit); 2164 } 2165 } 2166 } 2167 } 2168 void TAreaScanWindow::GetTitleY(int i, int titlesy, char *buf, bool reduceLines) { 2169 TCoorSystem *pCoorSys; 2170 switch (eOutputType) 2171 { 2172 case otReciprokeLatticeBitmap: 2173 case otMatrixBitmap: 2174 pCoorSys= &AltCoorSys; 2175 break; 2176 2177 default: 2178 pCoorSys= &CoorSys; 2179 } 2180 2181 if ( bShowPsdContinuous && m_PsdContinousType==PsdEnergyData ) { // Energiespektrum aktiv 2182 // keine Zahlenwerte (Einteilung der Skala unbekannt (theoretisches Maximum von 1 entspräche integraler Intensität) 2183 strcpy(buf, ""); 2184 2185 // letzte Beschriftung = Beschriftung der Ordinaten-Achse 2186 if ( i==tilesy ) { 2187 TPlotWindow::GetTitleY(i, titlesy, buf, reduceLines); 2188 if ( !reduceLines ) { 2189 if ( pCoorSys->yScal==sLinear ) sprintf(buf, szFrequentLi); 2190 else if ( pCoorSys->yScal==sLogarithmic ) sprintf(buf, szFrequentLo); 2191 } // ansonsten <buf> unverändert lassen; d.h. "linear"/ "log10 skaliert" 2192 } 2193 } else { 2194 // Zahlenwerte bzw. "linear"/ "log 10" 2195 TPlotWindow::GetTitleY(i, titlesy, buf, reduceLines); 2196 2197 // letzte Beschriftung = Beschriftung der Ordinaten-Achse 2198 if ( i==tilesy ) { 2199 switch ( eOutputType ) { 2200 case otReciprokeLatticeBitmap: 2201 sprintf(buf, "qz"); 2202 break; 2203 2204 case otMatrixBitmap: 2205 if ( reduceLines ) sprintf(buf, szAngleOmegaUnitEZ, mlGetAxisName(nOmega)); 2206 else sprintf(buf, szAngleOmegaUnit, mlGetAxisName(nOmega), mlGetUnitName(nOmega)); 2207 break; 2208 2209 // ansonsten <buf> unverändert lassen: dann wird "linear"/ "log 10" beschriftet 2210 } 2211 } 2212 } 2213 } 2214 2215 //############################################################################# 2216 // Read/Write (Reportdatei) 2217 //############################################################################# 2218 2219 //! Funktion laedt die zu einer .psd datei gehoerigen zusatzinfos 2220 //! Rueckkehrcode False wenn Fehler bei oeffnen der Datei, wenn weniger als 15 2221 //! Punkte in der Datei waren oder das vorgefundene Format(Titelzeile) nicht 2222 //! stimmt 2223 //! true sonst 2224 BOOL TAreaScanWindow::LoadReport( void ) 2225 { 2226 // es sind keine Zusatzinfos enthalten 2227 ReportUse.bIntegral= ReportUse.bTime= ReportUse.bMonitor= ReportUse.bAbsorber= FALSE; 2228 2229 TTxtRead ReportFile( GetRepFileName() ); // Datei öffenen 2230 if ( !ReportFile.Exists() || (ReportFile.GetLines() < 3) ) return FALSE; 2231 2232 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 2233 2234 // Kennzeichnung Reportdatei 2235 char *Line= ReportFile.NextLine(); 2236 if ( !strcmp(Line, "# Report:") ) { 2237 SetCursor( hOldCursor ); 2238 return FALSE; 2239 } 2240 2241 // 2.Zeile: Einlesen welche Zusatzinfos sind vorhanden 2242 Line= ReportFile.NextLine(); 2243 int EntryCount= 0; 2244 char *Entry= strtok( Line, " :\n\r" ); // den ersten Eintrag auslesen 2245 while ( Entry ) { //! spaltenweises Einlesen der Einträge (enden jeweils mit Leerzeichen/ Doppelpunkt/ Zeilenumbruch) 2246 bool bValidEntry= true; 2247 if ( !strcmp(Entry, "IntegralIntensity") ) 2248 ReportUse.bIntegral= TRUE; 2249 else if ( !strcmp(Entry, "MeasurementTime") ) 2250 ReportUse.bTime= TRUE; 2251 else if ( !strcmp(Entry, "MonitorSignal") ) 2252 ReportUse.bMonitor= TRUE; 2253 else if ( !strcmp(Entry, "AbsorberPosition") ) 2254 ReportUse.bAbsorber= TRUE; 2255 else if ( !strcmp(Entry, "Omega") || !strcmp(Entry, "Theta") || !strcmp(Entry, "MaxIntensity") || !strcmp(Entry, "PeakPosition") ) 2256 /*sind auch gültige Einträge*/; 2257 else 2258 bValidEntry= false; // ansonsten unbekannt 2259 2260 if ( bValidEntry ) EntryCount++; 2261 Entry= strtok( NULL, " :\n\r" ); // den nächsten Eintrag auslesen 2262 } 2263 if (EntryCount < 4) { 2264 SetCursor( hOldCursor ); 2265 return FALSE; 2266 } 2267 2268 // erstellen eines formatierten Strings abhaengig von den Zusatzinfos 2269 char buf[MaxString]; 2270 strcpy(buf, ""); 2271 strcat(buf, "%d"); 2272 for (int i= 0; i < min(8, EntryCount)/*max. Platz für 8 Einträge*/; i++) 2273 strcat(buf, " %f"); 2274 2275 ScanReport->New(); 2276 ScanReport2->New(); 2277 2278 // Textzeilen mit den Daten einlesen 2279 while ( !ReportFile.IsEOF() ) { // zeilenweise 2280 Line= ReportFile.NextLine(); 2281 // die ersten 4 Infos sind immer da, die folgenden je nach Scan 2282 float fOmega= 0, fTheta= 0, fMax= 0, fPeak= 0; 2283 float fValue[4]; 2284 fValue[0]= fValue[1]= fValue[2]= fValue[3]= 0; 2285 sscanf( Line, buf, &EntryCount, &fOmega, &fTheta, &fMax, &fPeak, &fValue[0], &fValue[1], &fValue[2], &fValue[3] ); 2286 2287 // der Rest gilt als Zusatzinfo (je nachdem was in der 2. Zeile angegeben wurde - in folgender Reihenfolge:) 2288 float fIntegral= 0, fTime= 0, fMonitor= 0, fAbsorber= 0; 2289 int Idx= 0; 2290 if ( ReportUse.bIntegral ) 2291 fIntegral= fValue[Idx++]; 2292 if ( ReportUse.bTime ) 2293 fTime= fValue[Idx++]; 2294 if ( (ReportUse.bMonitor) || (Monitor) ) 2295 fMonitor= fValue[Idx++]; 2296 if ( ReportUse.bAbsorber ) 2297 fAbsorber= fValue[Idx++]; 2298 2299 ScanReport->PAdd( fOmega, fTheta, fIntegral ); // 1.Reportkurve 2300 ScanReport2->PAdd( fTime, fMonitor, fAbsorber); // 2.Reportkurve 2301 } 2302 SetCursor( hOldCursor ); 2303 if ( ScanReport->GetPNumber()<3 ) return FALSE; 2304 2305 return TRUE; 2306 }; 2307 //***************************************************************************** 2308 2309 //! speichert die zur Datenbasis gehoerigen zusatzinfos in einer Datei unter 2310 //! dem aktuellen Dateinamen mit der Extension .rep ab 2311 //! Rueckkehrcode immer true 2312 BOOL TAreaScanWindow::SaveReport( void ) 2313 { 2314 float fOmega, fIntegral, fTheta; 2315 char buf[ MaxString *3]; 2316 char fmt[ MaxString *3]; 2317 int hFile, cnt; 2318 OFSTRUCT of; 2319 2320 hFile= OpenFile( GetRepFileName(), &of, OF_CREATE ); 2321 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 2322 2323 //! Headerteil anlegen in abhaengigkeit von den vorhandenen zusatzinfos 2324 sprintf(buf, "# Report: "); 2325 _lwrite( hFile, (LPSTR) buf, strlen( buf ) ); 2326 2327 strcpy( buf, EOL ); 2328 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2329 2330 sprintf(buf, "ScanId : Omega : Theta : MaxIntensity : PeakPosition "); 2331 if (ReportUse.bIntegral ) 2332 strcat( buf, ": IntegralIntensity " ); 2333 if (ReportUse.bTime || ( Monitor != 0) ) 2334 strcat( buf, ": MeasurementTime " ); 2335 if ( ReportUse.bMonitor || ( Monitor != 0 ) ) 2336 strcat( buf, ": MonitorSignal " ); 2337 if (ReportUse.bAbsorber) 2338 strcat( buf, ": AbsorberPosition " ); 2339 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2340 2341 strcpy( buf, EOL ); 2342 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2343 2344 ScanReport->SetPP(); 2345 ScanReport2->SetPP(); 2346 cnt= 0; 2347 //! alle zusatzinfos in Tabelle speichern +datei schliessen 2348 while ( ScanReport->PGet( fOmega, fTheta, fIntegral ) ) 2349 { 2350 char buf2[MaxString]; 2351 float fdummy, fPeakPos, fTime, fMonitor, fAbsorber; 2352 TCurve* DummyCurve= lpDBase->GetCurve( cnt); 2353 sprintf(fmt, "%d %s %s %.0f %s", cnt, szODF, szTDF, DummyCurve->GetMax(1), szTDF ); 2354 DummyCurve->GetGravityCenter(fPeakPos, fdummy, fdummy); 2355 ScanReport2->PGet(fTime, fMonitor, fAbsorber); 2356 if (VisualDB.bPsd) 2357 fPeakPos= fTheta + fPeakPos; 2358 if ( ReportUse.bIntegral ) 2359 { 2360 sprintf(buf2, " %.0f", fIntegral); 2361 strcat( fmt, buf2 ); 2362 } 2363 if ( ReportUse.bTime ) 2364 { 2365 sprintf(buf2, " %.3f", fTime); 2366 strcat( fmt, buf2 ); 2367 } 2368 if ( ReportUse.bMonitor || ( Monitor != 0 ) ) 2369 { 2370 sprintf(buf2, " %.0f", fMonitor); 2371 strcat( fmt, buf2 ); 2372 } 2373 if ( ReportUse.bAbsorber ) 2374 { 2375 sprintf(buf2, " %.3f", fAbsorber); 2376 strcat( fmt, buf2 ); 2377 } 2378 sprintf( buf, fmt, fOmega, fTheta, fPeakPos ); 2379 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2380 strcpy( buf, EOL ); 2381 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2382 cnt++; 2383 } 2384 _lclose( hFile ); 2385 SetCursor( hOldCursor ); 2386 return TRUE; 2387 }; 2388 2389 //############################################################################# 2390 // Read/Write (psd-Datei) 2391 //############################################################################# 2392 2393 //! liest gespeicherte Kurve (.psd) 2394 //! Rueckkehrcode false wenn Fehler beim oeffnen der Datei, Extension ungl. 2395 //! .psd, fehlerhaften Headerinfo. oder keine Eintraege nach[DATA] 2396 //! sonst auch false (fehler) 2397 BOOL TAreaScanWindow::LoadOldData() 2398 { 2399 float omega, theta, intens, channel; 2400 //! FIX Fehler 39 2401 int cnt, column, rows; 2402 2403 //! ins Arbeitverzeichnis wechseln + 'Datei nachladen'-Dialog oeffnen + Dateinamen prüfen 2404 char NewFilename[ _MAX_PATH ]; 2405 sprintf( NewFilename, "*.%s", szExtension ); 2406 _chdir( szDataPath ); 2407 if ( !FileOpenDialog( szMsgLine210, szFilter, NewFilename, szDataPath ) ) 2408 return FALSE; // 'Abbruch' geklickt 2409 if ( strlen(NewFilename)==0 || strcmp(NewFilename, "*")==0 ) 2410 return FALSE; 2411 char drv[ _MAX_DRIVE+1 ], dir[ _MAX_DIR+1 ], name[ _MAX_FNAME+1 ], ext[ _MAX_EXT+1 ]; 2412 _splitpath( NewFilename, drv, dir, name, ext ); 2413 char buf[MaxString]; 2414 sprintf( buf, ".%s", szExtension); 2415 if ( _stricmp(ext, buf)!=0 ) 2416 return FALSE; 2417 strcpy( FileName, NewFilename); 2418 2419 StopSensorContinuous(); 2420 Steering.Reset(); 2421 bAreaScanStarted= FALSE; // für Steering.Reset() abschalten 2422 bInterrupted= FALSE; 2423 2424 //*** Database freigeben, Fenster neu zeichnen 2425 lpDBase->New(); 2426 nActiveScan= 0; 2427 MainCurve= lpDBase->GetCurve( nActiveScan ); 2428 UpdateWnd(); 2429 2430 // set waiting cursor 2431 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 2432 2433 //*** Datei öffnen, Header einladen 2434 TTxtRead Datei( FileName ); 2435 SetInfo( szMsgLine313 ); 2436 if ( !LoadMeasurementInfo(Datei) ) { 2437 SetCursor( hOldCursor ); // restore cursor before waiting cursor 2438 MessageBox( szMsgLine014, szMsgFailure, MBINFO ); 2439 return FALSE; 2440 } 2441 2442 // zeilenweises Einlesen der Reihen 2443 TCurve *TheCurve= 0; 2444 rows= 1; 2445 Datei.Restart(); 2446 bool DataGef= false; 2447 SetInfo( szMsgLine314 ); 2448 while ( !Datei.IsEOF() ) { // zeilenweise 2449 char *line= Datei.NextLine(); // nicht freigeben, das erleigt TTxtRead für uns 2450 if ( strstr(line, "[Data]") ) { // [Data] gefunden :-) 2451 DataGef= true; 2452 continue; // Zeile überlesen 2453 } 2454 if ( !DataGef ) continue; // solange [Data] nicht gefunden: Zeilen überlesen 2455 2456 //! alle 5 gelesenen Scans Info ausgeben 2457 if ( !(lpDBase->GetCNumber() % 5) ) { 2458 sprintf( buf, szMsgLine211, lpDBase->GetCNumber() ); 2459 SetInfo( buf ); 2460 } 2461 2462 // letzte Kurve auswählen (Daten dort hinein schreiben) 2463 TheCurve= lpDBase->GetCurve( lpDBase->GetCNumber()-1 ); 2464 //07.05.2004 TheCurve->FastOpen(); 2465 2466 //! in Abhängigkeit von Detektor der Datenbasis (Psd oder 0-dim.) den Thetastartwert je Kurve berechnen 2467 theta= (VisualDB.bPsd) ? 0.0 : dThetaMin + (rows - 1) * dOmegaWidth * VisualDB.dMoveRelation - 0.5 * VisualDB.dThetaWindow; 2468 channel= 0.0; 2469 column= 0; 2470 2471 char *actual= strtok( line, " \t\n\r" ); // den ersten Messwert auslesen 2472 while ( actual ) { //! spaltenweises Einlesen der Messwerte (enden jeweils mit Leerzeichen/ Tab/ Zeilenumbruch) 2473 intens= atof( actual ); 2474 2475 // Messwert in Kurve speichern 2476 if ( column <= nLastReadColumn ) 2477 { 2478 if ( column >= nFirstReadColumn ) 2479 TheCurve->PAdd( theta, intens, channel ); //07.05.2004 FastP... 2480 column++; 2481 channel += nAddedChannels; 2482 //! in Abhängigkeit von Detektor der Datenbasis (Psd oder 0-dim.) díe Scanreportwerte der Datenbasis 2483 theta += (VisualDB.bPsd) ? (fPsdRange) * nAddedChannels : dThetaWidth; // contains here the PsdStep 2484 } 2485 actual= strtok( NULL, " \t\n\r" ); // den nächsten Messwert auslesen 2486 } 2487 //07.05.2004 TheCurve->FastClose(); 2488 if ( column>0 ) lpDBase->AddCurve( ); // nur neue Kurve anhängen, wenn TheCurve benutzt wurde; d.h. columns>0 2489 rows++; //! FIX Fehler 39 2490 } 2491 if ( !DataGef ) { // [Data] nicht vorhanden 2492 SetCursor( hOldCursor ); // restore cursor before waiting cursor 2493 return FALSE; 2494 } 2495 2496 if ( rows>1 ) lpDBase->DelCurve(); // die zuletzt selbst angehängte Kurve löschen (wäre für nächste Zeile gewesen, die nicht mehr gekommen ist) 2497 2498 //! Bereich des PSD aus Min und Max der letzten Kurve ermitteln 2499 TheCurve= lpDBase->GetCurve( lpDBase->GetCNumber()-1 ); 2500 fPsdRange= TheCurve->GetMax( 0 ) - TheCurve->GetMin( 0 ); 2501 2502 //*** Generation of ScanRep from ranges which corrections of measurement area 2503 { 2504 //! FIX Fehler 39 2505 omega= VisualDB.dOmegaMin; 2506 theta= VisualDB.dThetaMinFirst; 2507 //! unterscheiden O2T und Standard-Scan 2508 if (dThetaMin == dThetaMax) 2509 dThetaWidth= 0.0; 2510 else 2511 dThetaWidth= dOmegaWidth * dMoveRelation; 2512 //! dOmegaMax= dOmegaMin + dOmegaWidth * ( lpDBase->GetCNumber() - 1 ); 2513 2514 //! test ob zugehoerige reportdatei exist. bzw. defekt ist 2515 if ( !LoadReport() ) 2516 { 2517 char *msg= new char[ strlen(szMsgLine030) + strlen(GetRepFileName()) + 1 ]; // + Nullterminierung 2518 sprintf(msg, szMsgLine030, GetRepFileName() ); 2519 MessageBox( msg, szMsgFailure, MBINFO ); 2520 _FREELIST(msg); 2521 ScanReport->New(); 2522 //07.05.2004 ScanReport->FastOpen(); 2523 ScanReport2->New(); 2524 //07.05.2004 ScanReport2->FastOpen(); 2525 //! ScanReport erstellen 2526 float dummy; 2527 for ( cnt= 0; cnt < lpDBase->GetCNumber(); cnt++ ) 2528 { 2529 //! NEU! Fehler 33 2530 TheCurve= lpDBase->GetCurve(cnt); 2531 TheCurve->GetGravityCenter(dummy, intens, dummy); 2532 ScanReport->PAdd( omega, theta, intens ); //07.05.2004 FastP... 2533 dummy= 0.0; 2534 ScanReport2->PAdd(dummy, dummy, dummy); //07.05.2004 FastP... 2535 omega += dOmegaWidth; 2536 theta += dThetaWidth; 2537 } 2538 //07.05.2004 ScanReport2->FastClose(); 2539 //07.05.2004 ScanReport->FastClose(); 2540 } 2541 } 2542 2543 //*** Fenster neu zeichnen 2544 //! automatisch Bitmap errechnen wenn entspr. Ausgabetyp gewaehlt 2545 if ( eOutputType==otReciprokeLatticeBitmap || eOutputType==otMatrixBitmap ) 2546 BSource->FormatDBaseToBitmapSource(); 2547 UpdateWnd(); 2548 SetInfo( szMsgLine212 ); 2549 2550 //**** Daten aquirieren Peak- und Cross-Scan speichern ********************** 2551 #ifdef Peak_and_Cross //! ? nicht eingeschaltet ?
2552 float psdtheta, intens, channel, maxintens= 0.0; 2553 int maxcu, maxch; 2554 XShift= 0.0; 2555 for ( Idx= 0; Idx < lpDBase->GetCNumber(); Idx++ ) 2556 { 2557 TheCurve= lpDBase->GetCurve( Idx ); 2558 TheCurve->GetGravityCenter( psdtheta, intens, channel, 2 ); 2559 if ( intens > maxintens ) 2560 { 2561 maxintens= intens; 2562 maxcu= Idx; 2563 maxch= channel; 2564 } 2565 } 2566 TheCurve= lpDBase->GetCurve( maxcu ); 2567 *SecondCurve= *TheCurve; 2568 SaveSecondCurve(); 2569 SecondCurve->Delete(); 2570 for ( Idx= 0; Idx < lpDBase->GetCNumber(); Idx++ ) 2571 { 2572 TheCurve= lpDBase->GetCurve( Idx ); 2573 TheCurve->SetPP( maxch ); 2574 TheCurve->PGet( psdtheta, intens, channel ); 2575 psdtheta= OmegaMin + Idx * OmegaWidth; 2576 SecondCurve->PAdd( psdtheta, intens, channel ); 2577 } 2578 // Speichern der Curven 2579 SaveSecondCurve();
2580 #endif 2581 2582 SetCursor( hOldCursor ); // restore cursor before waiting cursor 2583 bFileChanged= FALSE; 2584 bIsNewFile= FALSE; 2585 bOldDataLoaded= TRUE; 2586 return TRUE; 2587 }; 2588 //***************************************************************************** 2589 2590 //! Funktion speichert einen Messdatensatz 2591 //! 1.Parameter gibt an ob neuer Dateiname zu waehlen ist (SaveWithNewName) 2592 //! oder ob automatisch unter altem Namen (NoAskForSave) gespeichert werden 2593 //! soll 2594 //! Rueckkehrcode False wenn Fehler bei anlegen der Datei oder bei speichern 2595 //! der headerinfos sonst immer true 2596 BOOL TAreaScanWindow::SaveFile( EAskType ask ) 2597 { 2598 TCurve *TheCurve; 2599 float fIntensity; 2600 float d0, d2; 2601 char msg[ MaxString ]; 2602 int hFile, idx, numbercolumn, nCIdx; 2603 OFSTRUCT of; 2604 2605 //! anlegen der Datei (event. mit eingabe des Dateinamen) 2606 if ( !TPlotWindow::SaveFile( ask ) ) 2607 return FALSE; 2608 2609 //*** explicite repaint of window, since it's normally not possible. 2610 UpdateWnd(); 2611 2612 //! speichern der reportkurve 2613 SaveReport(); 2614 2615 //**************************** 2616 //! ueberschreiben der Datei mit Headerinfo. 2617 if ( !SaveMeasurementInfo( FALSE ) ) 2618 { 2619 MessageBox( szMsgLine014, szMsgFailure, MBINFO ); 2620 return FALSE; 2621 } 2622 2623 hFile= OpenFile( FileName, &of, OF_WRITE ); 2624 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 2625 2626 // Daten an den Header anhaengen 2627 _llseek( hFile, 0, SEEK_END ); 2628 char *buf; 2629 // 1. Scan ist noch nicht mit gueltigen Daten belegt 2630 if ( !bSaveContinuous || lpDBase->GetCNumber()>1 ) { 2631 numbercolumn= lpDBase->GetCurve( 0 )->GetPNumber(); 2632 buf= new char [ max(20 * numbercolumn, strlen(szMsgLine028)+21/*Platz für 2 ints und Nullterminierung*/) ]; 2633 //! alle Kurven der Datenbasis durchlaufen und jeweils alle Intens.werte 2634 //! der Kurve in Datei ablegen 2635 for ( nCIdx= 0; nCIdx < lpDBase->GetCNumber(); nCIdx++ ) 2636 { 2637 sprintf( buf, szMsgLine028, nCIdx + 1, lpDBase->GetCNumber() ); 2638 SetInfo( buf ); 2639 2640 TheCurve= lpDBase->GetCurve( nCIdx ); 2641 TheCurve->SetPP(); 2642 //07.05.2004 TheCurve->FastOpen(); 2643 for ( idx= 0; idx < numbercolumn; idx++ ) 2644 { 2645 if ( TheCurve->PGet( d0, fIntensity, d2 ) ) //07.05.2004 FastP... 2646 { //! formatieren der Intensitaetswerte mit untersch. Genauigkeit 2647 // 22.04.2003 Kullmann+Reinecker: while(1)-Schleifen durch if-then-else ersetzt 2648 if ( 0.00001 > fIntensity ) 2649 sprintf( msg, "0 " ); 2650 else if ( 10.0 > fIntensity ) 2651 sprintf( msg, "%.4f ", fIntensity ); 2652 else if ( 100.0 > fIntensity ) 2653 sprintf( msg, "%.3f ", fIntensity ); 2654 else if ( 1000.0 > fIntensity ) 2655 sprintf( msg, "%.2f ", fIntensity ); 2656 else 2657 sprintf( msg, "%.1f ", fIntensity ); 2658 } 2659 else 2660 strcpy( msg, "0 " ); 2661 if ( 0 == idx ) 2662 strcpy( buf, msg ); 2663 else 2664 strcat( buf, msg ); 2665 } 2666 //! ablegen einer Kurve als zeile in Datei 2667 strcat( buf, EOL ); 2668 //07.05.2004 TheCurve->FastClose(); 2669 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2670 } 2671 _FREELIST(buf); 2672 } 2673 2674 //! schliessen der Datei 2675 _lclose( hFile ); 2676 SetCursor( hOldCursor ); 2677 bFileChanged= FALSE; 2678 return TRUE; 2679 }; 2680 //***************************************************************************** 2681 2682 //! haengt aktuelles Kurve an Datei mit FileName an 2683 //! aufruf nur bei kontinuierlichem Speichern 2684 //! Rueckkehrcode immer true 2685 BOOL TAreaScanWindow::UpdateFile( void ) 2686 { 2687 TCurve* TheCurve; 2688 float fIntensity; 2689 float d0, d2; 2690 char buf[ MaxString ], fmt[ MaxString ]; 2691 int hFile, idx, numbercolumn; 2692 OFSTRUCT of; 2693 //! nicht von Diffr.gruppe auskommentiert 2694 //! int nOldId= mlGetAxis(); 2695 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 2696 2697 //! Datei oeffnen + Statusinfo ausgeben 2698 hFile= OpenFile( FileName, &of, OF_WRITE ); 2699 _llseek( hFile, 0, SEEK_END ); 2700 lpDBase->GetLastCurve() ->SetPP(); // first point of last curve 2701 sprintf( buf, szMsgLine029, lpDBase->GetCNumber() - 1 ); 2702 SetInfo( buf ); 2703 2704 //! letzte Kurve der Datenbasis auswaehlen + alle Intens.werte der Kurve 2705 //! auslesen und als zeile an Datei anhaengen 2706 numbercolumn= lpDBase->GetCurve( 0 )->GetPNumber(); 2707 TheCurve= lpDBase->GetLastCurve(); 2708 // 07.05.2004 TheCurve->FastOpen(); 2709 TheCurve->SetPP(); 2710 for ( idx= 0; idx < numbercolumn; idx++ ) 2711 { 2712 //! bestimmt anzahl dez.-stellen und legt Intensitaetswert demenstpr. 2713 //! formatiert ab 2714 if ( (TheCurve->PGet(d0, fIntensity, d2)) && (fIntensity != 0.0) ) //07.05.2004 FastP... 2715 { 2716 short pp= 3 - log10( fIntensity ); 2717 if ( pp < 0 ) 2718 pp= 0; 2719 strcpy( fmt, "%.3f " ); 2720 fmt[ 2 ]= ( char ) ( '0' + pp ); 2721 sprintf( buf, fmt, fIntensity ); 2722 goto Ready; 2723 } 2724 sprintf( buf, "0 " ); 2725 Ready: 2726 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2727 } 2728 // 07.05.2004 TheCurve->FastClose(); 2729 strcpy( buf, EOL ); 2730 _lwrite( hFile, ( LPSTR ) buf, strlen( buf ) ); 2731 2732 //! Datei schliessen 2733 _lclose( hFile ); 2734 SetCursor( hOldCursor ); 2735 bFileChanged= FALSE; 2736 return TRUE; 2737 }; 2738 2739 //############################################################################# 2740 // Read/Write (psd-Datei - Kommentar+Header) 2741 //############################################################################# 2742 2743 //! laden der Messungsinfos aus einer .psd datei 2744 //! hFile ist Filehandle der Messdatei 2745 //! Rueckkehrcode False wenn Datei zu kurz ,[HEADER] nicht vorhanden, 2746 //! Filetyp ungl. 1 oder OmegaStep= 0 2747 //! true sonst 2748 BOOL TAreaScanWindow::LoadMeasurementInfo( TTxtRead &aFile ) { 2749 int columns; 2750 2751 nFirstReadColumn= nLastReadColumn= columns= 0; 2752 dThetaOffset= 0.0; 2753 //! FIX Fehler 39 2754 VisualDB.bPsd= FALSE; 2755 //! Messkanal auf default-wert 2756 nMeasurementChannel= 0; 2757 //! Kullmann, Reinecker: fehlende Initialisierungen nachgebessert 2758 fPsdRange= fMaxTime= 0; 2759 dThetaMin= dThetaMax= dThetaWindow= VisualDB.dThetaWindow= dThetaWidth= 0; 2760 dMoveRelation= VisualDB.dMoveRelation= 0; 2761 dOmegaMin= VisualDB.dOmegaMin= dOmegaMax= VisualDB.dOmegaMax= 0; 2762 nAddedChannels= 1; 2763 eSaveFormat= ffStandardFile; 2764 2765 // Header-Informationen auswerten 2766 aFile.Restart(); 2767 bool HeaderGef= false; 2768 while ( !aFile.IsEOF() ) { // zeilenweise einlesen 2769 char *line= aFile.NextLine(); // line nicht freigeben, das erledigt TTxtRead 2770 if ( strstr(line, "[Header]") ) { // [Header] gefunden :-) 2771 HeaderGef= true; 2772 continue; // Zeile überlesen 2773 } 2774 if ( !HeaderGef ) continue; // solange [Header] nicht gefunden: Zeilen überlesen 2775 if ( strstr(line, "[Data]") ) break; // bei [Data]: Header komplett = fertig :-) 2776 2777 2778 char *keyword= strtok( line, " =\n\r" ); // den ersten Teil vor "=" auslesen 2779 char *info= strtok( NULL, " =\n\r" ); // den ersten Teil nach "=" auslesen 2780 while ( keyword && info ) { // solange weitere Daten in dieser Zeile 2781 2782 /*if ( !strcmp(keyword, "Date") || 2783 !strcmp(keyword, "DataRows") || 2784 !strcmp(keyword, "Time") || 2785 !strcmp(keyword, "HV") ) 2786 { 2787 // einfach überlesen 2788 2789 } else */if ( !strcmp(keyword, "User") ) { 2790 MeasurementParameter.SetUser( info ); 2791 2792 } else if ( !strcmp(keyword, "Target") ) { 2793 MeasurementParameter.SetTarget( info ); 2794 2795 } else if ( !strcmp(keyword, "Substrat") ) { 2796 MeasurementParameter.SetTargetBulk( info ); 2797 2798 } else if ( !strcmp(keyword, "Reflection") ) { 2799 MeasurementParameter.SetReflection( info ); 2800 2801 } else if ( !strcmp(keyword, "Orientation") ) { 2802 MeasurementParameter.SetOrientation( info ); 2803 2804 } else if ( !strcmp(keyword, "DataColumns") ) { 2805 columns= atof( info ); 2806 2807 } else if ( !strcmp(keyword, "FirstColumn") ) { 2808 nFirstReadColumn= atof( info ); 2809 2810 } else if ( !strcmp(keyword, "LastColumn") ) { 2811 nLastReadColumn= atof( info ); 2812 2813 } else if ( !strcmp(keyword, "WaveLength") ) { 2814 MeasurementParameter.SetWaveLength( info ); 2815 2816 } else if ( !strcmp(keyword, "PsdStep") ) { 2817 fPsdRange= atof( info ); 2818 //! Gradwert in Sekunden umrechnen 2819 // ::fPsdRange *= 3600.0; 2820 //! FIX Fehler 39 2821 VisualDB.bPsd= TRUE; 2822 2823 } else if ( !strcmp(keyword, "ThetaMin") ) { 2824 dThetaMin= atof( info ); 2825 2826 } else if ( !strcmp(keyword, "ThetaMax") ) { 2827 dThetaMax= atof( info ); 2828 2829 } else if ( !strcmp(keyword, "MoveRelation") ) { 2830 dMoveRelation= atof( info ); 2831 //! FIX Fehler 39 2832 VisualDB.dMoveRelation= dMoveRelation; 2833 2834 } else if ( !strcmp(keyword, "OmegaMin") ) { 2835 dOmegaMin= atof( info ); 2836 //! FIX Fehler 39 2837 VisualDB.dOmegaMin= dOmegaMin; 2838 2839 //! FIX Fehler 39 2840 } else if ( !strcmp(keyword, "OmegaMax") ) { 2841 dOmegaMax= atof( info ); 2842 VisualDB.dOmegaMax= dOmegaMax; 2843 2844 } else if ( !strcmp(keyword, "OmegaStep") ) { 2845 dOmegaWidth= atof( info ); 2846 2847 //! FIX Fehler 39 2848 } else if ( !strcmp(keyword, "ThetaWindow") ) { 2849 dThetaWindow= atof( info ); 2850 VisualDB.dThetaWindow= dThetaWindow; 2851 dThetaWidth= dThetaWindow / (columns - 1); 2852 2853 } else if ( !strcmp(keyword, "TimePerScan") ) { 2854 fMaxTime= atof( info ); 2855 2856 } else if ( !strcmp(keyword, "PsdAddedChannels") ) { 2857 nAddedChannels= atoi( info ); 2858 2859 } else if ( !strcmp(keyword, "MeasurementChannel") ) { 2860 nMeasurementChannel= atoi( info ); 2861 2862 //! Test auf folgende Eintraege bei DB-Zusammensetzung 2863 } else if ( bComposeDB ) { 2864 if ( !strcmp( keyword, "Point_Number" ) ) { 2865 columns= atoi( info ); 2866 } else if ( !strcmp( keyword, "Zerlegung" ) ) { 2867 if ( !strcmp( info, "PSD" ) ) VisualDB.bPsd= TRUE; 2868 } else { 2869 nFirstReadColumn= 0; 2870 nLastReadColumn= columns; 2871 } 2872 2873 } else if ( !strcmp(keyword, "FileType") ) { 2874 if ( !strcmp(info, "1") || !strcmp(info, "Standard") ) 2875 eSaveFormat= ffStandardFile; 2876 else 2877 return FALSE; // falsches Dateiformat 2878 } 2879 2880 keyword= strtok( NULL, " =\n\r" ); // den nächsten Teil vor "=" auslesen 2881 info= strtok( NULL, " =\n\r" ); // den nächsten Teil nach "=" auslesen 2882 } 2883 } 2884 if ( !HeaderGef ) return FALSE; // [Header] nicht vorhanden 2885 2886 //! einige Headerwerte überprüfen und ggf. auf gültige Werte setzen 2887 if ( !nLastReadColumn ) 2888 nLastReadColumn= columns; 2889 else if ( nLastReadColumn > columns ) 2890 nLastReadColumn= columns; 2891 if ( !nFirstReadColumn ) 2892 nFirstReadColumn= 0; 2893 dThetaOffset= 0.0; 2894 if ( !dOmegaWidth ) { 2895 // 17.05.2004 Meldung wird sonst doppelt ausgegeben MessageBox( szMsgLine014, szMsgFailure, MBINFO ); 2896 return FALSE; 2897 } 2898 2899 //! FIX Fehler 39 2900 if ( VisualDB.bPsd) 2901 { 2902 VisualDB.fAngleStep= fPsdRange; 2903 VisualDB.fAngleRange= fPsdRange * (columns + 1) * nAddedChannels; 2904 //! psd-offset in kurve einrechnen 2905 VisualDB.dThetaMinFirst= dThetaMin - nMeasurementChannel * VisualDB.fAngleStep; 2906 VisualDB.dThetaMaxFirst= VisualDB.dThetaMinFirst + VisualDB.fAngleRange; 2907 //! psd-offset in kurve einrechnen 2908 VisualDB.dThetaMinLast= dThetaMax - nMeasurementChannel * VisualDB.fAngleStep; 2909 VisualDB.dThetaMaxLast= VisualDB.dThetaMinLast + VisualDB.fAngleRange; 2910 } 2911 else 2912 { 2913 VisualDB.fAngleStep= VisualDB.dThetaWindow / (columns - 1); 2914 VisualDB.fAngleRange= VisualDB.dThetaWindow; 2915 VisualDB.dThetaMinFirst= dThetaMin - 0.5 * VisualDB.dThetaWindow; 2916 VisualDB.dThetaMaxFirst= dThetaMin + 0.5 * VisualDB.dThetaWindow; 2917 VisualDB.dThetaMinLast= dThetaMax - 0.5 * VisualDB.dThetaWindow; 2918 VisualDB.dThetaMaxLast= dThetaMax + 0.5 * VisualDB.dThetaWindow; 2919 } 2920 return TRUE; 2921 }; 2922 //***************************************************************************** 2923 2924 //! Funktion speichert Headerinformationen zu einem Areascan in einer Datei 2925 //! 1.Parameter gibt an, ob die Datei neu erstellt(=0) werden soll oder nur 2926 //! aktualisiert (ungl. 0) werden soll 2927 //! Rueckkehrcode false wenn probleme beim erstellen bzw. oeffnen der Datei 2928 //! sonst immer true 2929 BOOL TAreaScanWindow::SaveMeasurementInfo( BOOL UpdateHeader ) 2930 { 2931 int hFile; 2932 UINT nSize; 2933 TCurve *Report= lpDBase->GetScanReport(); 2934 char buf[ MaxString + 1 ], buf2[ MaxString / 2 ], buf3[ MaxString / 2 ]; 2935 char format[ 2 * MaxString + 1 ]; 2936 int ival; 2937 OFSTRUCT of; 2938 SYSTEMTIME t; 2939 2940 //klier 01.03.2003 2941 SetMeasurementProtocolParameter(); 2942 SaveProtocolDiffractometryParameter(); 2943 2944 //! oeffnet oder erstellt Datei + wenn Fehler dann Meldung + abbruch 2945 if ( UpdateHeader ) 2946 hFile= OpenFile( FileName, &of, OF_WRITE ); 2947 else 2948 hFile= OpenFile( FileName, &of, OF_CREATE ); 2949 if ( hFile==HFILE_ERROR ) 2950 { 2951 MessageBox( sth_CannotOpenFile, szMsgFailure, MBSTOP ); 2952 return FALSE; 2953 } 2954 //! Systemzeit + datum holen 2955 GetLocalTime( &t ); 2956 //! Headerinformationen in String kopieren 2957 char *data= new char[ DATAOFFSET+1 ]; 2958 strcpy( format, "Comment=%s" ); 2959 sprintf( buf, format, MeasurementParameter.GetComment() ); 2960 strcpy( data, buf ); 2961 strcat( data, EOL ); 2962 2963 strcat( data, "[Header]" ); 2964 strcat( data, EOL ); 2965 strcpy( format, "User=%s Date=%02i.%02i.%i Time=%2d:%02d:%02d" ); 2966 sprintf( buf, format, MeasurementParameter.GetUser(), 2967 t.wDay, t.wMonth, t.wYear, t.wHour, t.wMinute, t.wSecond ); 2968 strcat( data, buf ); 2969 strcat( data, EOL ); 2970 2971 strcpy( format, "DataRows=%d DataColumns=%d FileType=%d" ); 2972 // HD 960106 2973 strcat( format, EOL ); 2974 strcat( format, "FirstColumn=0 LastColumns=%d" ); 2975 ival= lpDBase->GetCurve( 0 )->GetPNumber() + GetAdditionalColumns(); 2976 sprintf( buf, format, lpDBase->GetCNumber(), ival, ( BOOL ) ( eSaveFormat == ffStandardFile ), ival - 1 ); 2977 strcat( data, buf ); 2978 strcat( data, EOL ); 2979 2980 // aktuelle Bereiche abspeichern 2981 sprintf( format, "OmegaMin=%s OmegaStep=%s OmegaMax=%s", szODF, szOWF, szODF ); 2982 sprintf( buf, format, Report->GetMin( P_X ), dOmegaWidth, Report->GetMax( P_X ) ); 2983 strcat( data, buf ); 2984 2985 //klier 30.01.2003 Der Wert für das Offset wird mit ausgegeben 2986 // sprintf( format, " OmegaOffset=%s", szODF ); 2987 // sprintf( buf, format, mlGetOffset(nOmega) ); 2988 // strcat( data, buf ); 2989 strcat( data, EOL ); 2990 2991 sprintf( format, "ThetaMin=%s ThetaStep=%s ThetaMax=%s MoveRelation=%%.2f", szTDF, szTWF, szTDF ); 2992 //! in abhaengigkeit von art des Scans haben die Thetaeintraege verschiedene 2993 //! bedeutungen 2994 if (VisualDB.bPsd) 2995 sprintf( buf, format, Report->GetMin( P_Y ) - dPsdOffset, dOmegaWidth * VisualDB.dMoveRelation, Report->GetMax( P_Y ) - dPsdOffset, VisualDB.dMoveRelation ); //! speichern einer Psd-Datenbasis 2996 //! speichern einer SLD-DatenBasis mit zentren der Thetawindows als Thetawerte 2997 else 2998 sprintf( buf, format, VisualDB.dThetaMinFirst + 0.5* VisualDB.dThetaWindow, dOmegaWidth * VisualDB.dMoveRelation, VisualDB.dThetaMinFirst + 0.5* VisualDB.dThetaWindow + (Report->GetPNumber() - 1)* dOmegaWidth * VisualDB.dMoveRelation, VisualDB.dMoveRelation ); 2999 strcat( data, buf ); 3000 3001 //klier 30.01.2003 Der Wert für das Offset wird mit ausgegeben 3002 // sprintf( format, " ThetaOffset=%s", szTDF ); 3003 // sprintf( buf, format, mlGetOffset(nTheta) ); 3004 // strcat( data, buf ); 3005 strcat( data, EOL ); 3006 3007 strcpy( format, "Target=%s Reflection=%s Orientation=%s" ); 3008 MeasurementParameter.GetReflection(buf2); 3009 MeasurementParameter.GetOrientation(buf3); 3010 sprintf( buf, format, MeasurementParameter.GetTarget(), buf2, buf3 ); 3011 strcat( data, buf ); 3012 strcat( data, EOL ); 3013 3014 strcpy( format, "WaveLength=%.3f Current=%d HV=%d" ); 3015 sprintf( buf, format, MeasurementParameter.GetWaveLength(), MeasurementParameter.GetCurrent(), MeasurementParameter.GetVoltage() ); 3016 strcat( data, buf ); 3017 strcat( data, EOL ); 3018 3019 //! in Abhängigkeit vom Detektor (0-dim. oder psd ) Fehler 3020 if ( VisualDB.bPsd ) 3021 { 3022 strcpy( format, "TimePerScan=%.2f PsdStep=%.9f PsdAddedChannels=%d MeasurementChannel=%d" ); 3023 sprintf( buf, format, fMaxTime, (bOldDataLoaded) ? VisualDB.fAngleStep : VisualDB.fAngleStep / 3600.0 3024 /* GetPsd()->GetWidth()*/, nAddedChannels, 3025 nMeasurementChannel ); 3026 strcat( data, buf ); 3027 } 3028 else 3029 { 3030 //! FIX Fehler 39 3031 strcpy( format, "TimePerScan=%.2f ThetaWindow=%.2f" ); 3032 sprintf( buf, format, fMaxTime, VisualDB.dThetaWindow ); 3033 strcat( data, buf ); 3034 } 3035 //! auffüllen de Strings mit Leerzeichen + ablegen des Strings in der Datei 3036 //! + schliessen der Datei 3037 for ( nSize= strlen( data ); nSize < DATAOFFSET - 10; nSize++ ) 3038 data[ nSize ]= ' '; 3039 data[ nSize ]= 0x0; 3040 strcat( data, EOL ); 3041 strcat( data, "[Data]" ); 3042 strcat( data, EOL ); 3043 _lwrite( hFile, data, strlen( data ) ); 3044 _lclose( hFile ); 3045 _FREELIST(data); 3046 return TRUE; 3047 }; 3048 //***************************************************************************** 3049 3050 //! ? 3051 //! Rueckkehrcode bei ShiftedStandard ist die Anzahl der Psd-kanaele die 3052 //! benoetigt werden um den Thetabereich zu ueberdecken 3053 //! sonst immer 0 3054 int TAreaScanWindow::GetAdditionalColumns( void ) 3055 { 3056 if ( eSaveFormat != ffShiftedStandard ) 3057 return 0; 3058 if ( dOmegaWidth == 0.0 ) 3059 return 0; 3060 return GetShift( ( ( dOmegaMax - dOmegaMin ) / dOmegaWidth ) + 1 ); 3061 }; 3062 //***************************************************************************** 3063 3064 //! Funktion liefert zu Anzahl der Scans (1.Parameter) Anzahl der Psd-kanaele 3065 //! die benoetigt werden um den Thetabereich zu ueberdecken 3066 //! (nur bei ShiftedStan.) sonst 0 als Rueckkehrcode 3067 int TAreaScanWindow::GetShift( int ScanNumber ) 3068 { 3069 if ( GetPsd()->GetWidth() == 0.0 ) 3070 return 0; 3071 if ( eScanType == stStandardScan ) 3072 return 0; 3073 return ScanNumber * ( dOmegaWidth * dMoveRelation ) / GetPsd()->GetWidth(); 3074 }; 3075 //***************************************************************************** 3076 // Read/Write 3077 //***************************************************************************** 3078 3079 //! Zusammensetzen einer Datenbasis 3080 BOOL TAreaScanWindow::ComposeDB( void ) 3081 { 3082 //>>> 3083 TModalDlg * dlg; 3084 const int LLength= 2500; 3085 LPSTR lpBuf; 3086 char buf[ MaxString ]; 3087 float x, x2, x3, y, z, z2, z3; 3088 int hFile, cnt, idx, idx2; 3089 OFSTRUCT of; 3090 char name[ _MAX_PATH+1 ], oldname[ _MAX_PATH+1 ]; 3091 BOOL bReady= FALSE; 3092 TCurve *TheCurve; 3093 float dummy; 3094 3095 //! Aufruf des Dialoges DB zusammensetzen 3096 MaxFiles= 0; 3097 dlg= ( TComposeDBDlg * ) new TComposeDBDlg( this ); 3098 if ( dlg ) dlg->ExecuteDialog( GetHandle() ); 3099 _FREEOBJ(dlg); 3100 if ( MaxFiles <= 0 ) 3101 return TRUE; //! wenn Zahl keine Kurven 3102 3103 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 3104 bComposeDB= TRUE; 3105 bFileChanged= TRUE; 3106 //! neue DB 3107 lpDBase->New(); 3108 nActiveScan= 0; 3109 TheCurve= lpDBase->GetCurve( nActiveScan ); 3110 strcpy( name, FirstFile ); 3111 name[ max(0, strlen(name)-8) ]= '\0'; 3112 strcpy( oldname, name ); 3113 idx= idx2= atoi( &FirstFile[ max(0, strlen(FirstFile)-8) ] ); 3114 //! neuer Scan-Report 3115 ScanReport->New(); 3116 //! fuer jede Kurve Datei oeffnen + Header einlesen + Datenaufnahme 3117 for ( idx; idx < (idx2 + MaxFiles); idx++ ) 3118 { 3119 strcpy( name, oldname ); 3120 sprintf( buf, "%.4d.CRV", idx ); 3121 strcat( name, buf ); 3122 SetInfo(name); 3123 3124 TTxtRead Datei(name); 3125 if ( !LoadMeasurementInfo(Datei) ) { 3126 SetCursor( hOldCursor ); // restore cursor before waiting cursor 3127 return FALSE; 3128 } 3129 hFile= OpenFile( name, &of, OF_READ ); 3130 3131 nActiveScan= lpDBase->GetCNumber() - 1; 3132 TheCurve= lpDBase->GetLastCurve(); 3133 lpBuf= new char [ LLength ]; 3134 if ( !SetFPOnData( hFile ) ) 3135 { 3136 SetCursor(hOldCursor); 3137 return FALSE; 3138 } 3139 bReady= FALSE; 3140 for ( cnt= 0; !bReady; cnt++ ) 3141 switch ( GetFileLine( hFile, lpBuf, LLength ) ) 3142 { 3143 case R_Overflow: 3144 cnt++; 3145 bReady= TRUE; 3146 continue; 3147 3148 case R_EndOfFile: 3149 cnt++; 3150 bReady= TRUE; 3151 //Fehler? Kullmann+Reinecker: Fehlt hier ein break? 3152 3153 default: 3154 if ( 3 != sscanf( lpBuf, "%f %f %f", &x, &y, &z ) ) 3155 continue; 3156 if ( cnt == 0 ) 3157 x2= x; 3158 if ( VisualDB.bPsd ) 3159 x -= x2; 3160 TheCurve->PAdd( x, y, z ); 3161 } 3162 if ( idx < (idx2 + MaxFiles) - 1 ) 3163 lpDBase->AddCurve( ); // 10.04.2004 Parameterübergabe nicht mehr notwendig TheCurve->GetPNumber() 3164 _lclose( hFile ); 3165 TheCurve->GetGravityCenter(dummy, y, dummy); 3166 ScanReport->PAdd( z, x2 , y ); 3167 _FREELIST(lpBuf); 3168 } // for (idx... 3169 //! erste Datei wiederholt lesen 3170 //! Bestimmung der Report-Informationen fuer Omega, Theta, Relation, Schritt,.. 3171 3172 TTxtRead Datei(FirstFile); 3173 if ( !LoadMeasurementInfo(Datei) ) { 3174 SetCursor( hOldCursor ); // restore cursor before waiting cursor 3175 return FALSE; 3176 } 3177 ScanReport->SetPP(); 3178 ScanReport->PGet(x, z, y); 3179 ScanReport->SetPP( 1 ); 3180 ScanReport->PGet(x2, z2, y); 3181 ScanReport->SetPPLast(); 3182 ScanReport->PGet(x3, z3, y); 3183 if ( VisualDB.bPsd ) 3184 { 3185 if ( nLastReadColumn > 0 ) 3186 nAddedChannels= 4096 / (nLastReadColumn + 1); 3187 else 3188 nAddedChannels= 1; 3189 VisualDB.dOmegaMin= dOmegaMin= x; 3190 VisualDB.dOmegaMax= dOmegaMax= x3; 3191 dThetaMin= d2ThetaStart= z; 3192 dThetaMax= z3; 3193 dOmegaWidth= ( x3 - x ) / ( lpDBase->GetCNumber() - 1 ); 3194 dThetaWidth= ( z3 - z ) / ( lpDBase->GetCNumber() - 1 ); 3195 dMoveRelation= VisualDB.dMoveRelation= dThetaWidth / dOmegaWidth; 3196 TheCurve= lpDBase->GetCurve( 0 ); 3197 TheCurve->SetPP(); 3198 TheCurve->PGet(x, y, z); 3199 TheCurve->SetPP( 1 ); 3200 TheCurve->PGet(x2, y, z); 3201 VisualDB.fAngleStep= x2 - x; 3202 VisualDB.fAngleRange= VisualDB.fAngleStep * TheCurve->GetPNumber(); 3203 } 3204 else 3205 { 3206 VisualDB.dOmegaMin= dOmegaMin= x; 3207 VisualDB.dOmegaMax= dOmegaMax= x3; 3208 dThetaMin= d2ThetaStart= z; 3209 dThetaMax= z3; 3210 dOmegaWidth= ( x3 - x ) / ( lpDBase->GetCNumber() - 1 ); 3211 dThetaWidth= ( z3 - z ) / ( lpDBase->GetCNumber() - 1 ); 3212 dMoveRelation= VisualDB.dMoveRelation= dThetaWidth / dOmegaWidth; 3213 TheCurve= lpDBase->GetCurve( 0 ); 3214 TheCurve->SetPP(); 3215 TheCurve->PGet(x, y, z); 3216 TheCurve->SetPPLast(); 3217 TheCurve->PGet(x2, y, z); 3218 VisualDB.dThetaWindow= x2 - x; 3219 VisualDB.fAngleStep= VisualDB.dThetaWindow / (TheCurve->GetPNumber() - 1); 3220 VisualDB.fAngleRange= VisualDB.dThetaWindow; 3221 } 3222 VisualDB.dThetaMinFirst= dThetaMin; 3223 if (dThetaWidth != 0) 3224 VisualDB.dThetaMinLast= dThetaMin + (dOmegaMax - dOmegaMin) * dMoveRelation; 3225 else 3226 VisualDB.dThetaMinLast= dThetaMin; 3227 VisualDB.dThetaMaxFirst= dThetaMin + VisualDB.fAngleRange; 3228 VisualDB.dThetaMaxLast= VisualDB.dThetaMinLast + VisualDB.fAngleRange; 3229 //! Fenster-Aktualisierung + DB-Zusammenfassung deaktiviert 3230 UpdateWnd(); 3231 bComposeDB= FALSE; 3232 SetCursor(hOldCursor); 3233 return TRUE; 3234 }; 3235 //***************************************************************************** 3236 3237 //! Sichern einer aktuellen Kurve der DB in crv-Datei 3238 BOOL TAreaScanWindow::SaveDismantleCurve( int counter ) 3239 { 3240 int hFile; 3241 OFSTRUCT of; 3242 UINT nSize; 3243 char format[ MaxString ]; 3244 char buf[ 2 * MaxString ], buf2[ 20 ], buf3[ 20 ], fmt[ 30 ]; 3245 SYSTEMTIME t; 3246 float v, x, y, z, fOmega, fTheta; 3247 3248 //! Dateinamen anlegen 3249 sprintf( buf, "%.4d.CRV", counter ); 3250 strcpy( FileName, szDataPath ); 3251 strcat( FileName, DismantleFile ); 3252 strcat( FileName, buf ); 3253 SetInfo(FileName); 3254 //! Kurve auslesen 3255 MainCurve= lpDBase->GetCurve( counter ); 3256 ScanReport->SetPP( counter ); 3257 ScanReport->PGet( fOmega, fTheta, z ); 3258 MainCurve->SetPP(); 3259 //! Datei anlegen + Header 3260 hFile= OpenFile(FileName, &of, OF_CREATE); 3261 if ( hFile==HFILE_ERROR ) 3262 return FALSE; 3263 3264 _llseek (hFile, 0, SEEK_END ); 3265 sprintf( fmt, "%s %s %s\r\n", mGetSF(), "%.4f", "%.4f" ); 3266 // 07.05.2004 MainCurve->FastOpen(); 3267 GetLocalTime( &t ); 3268 char *data= new char[ DATAOFFSET + 1 ]; 3269 strcpy( format, "Comment=%s" ); 3270 sprintf( buf, format, MeasurementParameter.GetComment() ); 3271 strcpy( data, buf ); 3272 strcat( data, EOL ); 3273 strcat( data, "[Header]" ); 3274 strcat( data, EOL ); 3275 //! Neu im Header: Zerlegungs-Information 3276 if ( VisualDB.bPsd ) 3277 strcat( data, "Zerlegung=PSD" ); 3278 else 3279 strcat( data, "Zerlegung=SLD" ); 3280 strcat( data, EOL ); 3281 strcpy( format, "User=%s Date=%02i.%02i.%i Time=%2d:%02d:%02d DataOffset=%d" ); 3282 sprintf( buf, format, MeasurementParameter.GetUser(), t.wDay, t.wMonth, t.wYear, t.wHour, t.wMinute, t.wSecond, DATAOFFSET ); 3283 strcat( data, buf ); 3284 strcat( data, EOL ); 3285 strcpy( format, "Point_Number=%d FileType=Standard" ); 3286 sprintf( buf, format, MainCurve->GetPNumber()); 3287 strcat( data, buf ); 3288 strcat( data, EOL ); 3289 strcpy( format, "Target=%s Reflection=%s Orientation=%s" ); 3290 MeasurementParameter.GetReflection(buf2); 3291 MeasurementParameter.GetOrientation(buf3); 3292 sprintf( buf, format, MeasurementParameter.GetTarget(), buf2, buf3 ); 3293 strcat( data, buf ); 3294 strcat( data, EOL ); 3295 sprintf( format, "ArgumentMin=%s ArgumentWidth=%s ArgumentMax=%s Scanaxis=Theta", mGetDF(), mGetSF(), mGetDF() ); 3296 if ( VisualDB.bPsd ) 3297 sprintf( buf, format, fTheta + MainCurve->GetMin(0)*VisualDB.fAngleStep, 3298 (MainCurve->GetMax(0) - MainCurve->GetMin(0)) / MainCurve->GetPNumber(), 3299 MainCurve->GetMax(0) + fTheta); 3300 else 3301 sprintf( buf, format, MainCurve->GetMin(0), dThetaWidth, MainCurve->GetMax(0)); 3302 strcat( data, buf ); 3303 strcat( data, EOL ); 3304 strcpy( format, "WaveLength=%.3f Current=%d HV=%d" ); 3305 sprintf( buf, format, MeasurementParameter.GetWaveLength(), 3306 MeasurementParameter.GetCurrent(), MeasurementParameter.GetVoltage() ); 3307 strcat( data, buf ); 3308 strcat( data, EOL ); 3309 strcpy( format, "TimePerScan=%.2f" ); 3310 sprintf( buf, format, fMaxTime ); 3311 strcat( data, buf ); 3312 for ( nSize= strlen(data); nSize < DATAOFFSET - 10; nSize++ ) 3313 data[ nSize ]= ' '; 3314 data[ nSize ]= 0x0; 3315 strcat( data, EOL ); 3316 strcat( data, "[Data]" ); 3317 strcat( data, EOL ); 3318 _lwrite(hFile, data, strlen(data)); 3319 while ( MainCurve->PGet( x, y, z ) ) //07.05.2004 FastP... 3320 { 3321 if ( VisualDB.bPsd ) 3322 x += fTheta; 3323 ScanReport->SetPP( counter ); 3324 ScanReport->PGet( z, v, v ); 3325 sprintf( buf, fmt, x, y, z ); 3326 _lwrite( hFile, buf, strlen( buf ) ); 3327 } 3328 _lclose(hFile); 3329 // 07.05.2004 MainCurve->FastClose(); 3330 _FREELIST(data); 3331 bFileChanged= FALSE; 3332 return TRUE; 3333 }; 3334 //***************************************************************************** 3335 3336 //! Zerlegen der DB 3337 BOOL TAreaScanWindow::DismantleDB( void ) 3338 { 3339 //! Dialogboxaufruf 3340 TModalDlg *dlg= ( TDismantleDBDlg * ) new TDismantleDBDlg( this ); 3341 if ( dlg ) dlg->ExecuteDialog( GetHandle() ); 3342 _FREEOBJ(dlg); 3343 3344 //! alle Kurven durchlaufen und einzeln speichern 3345 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 3346 if ( strcmp(DismantleFile, "") ) 3347 for (int counter= 0; counter < lpDBase->GetCNumber(); counter++ ) 3348 if (!SaveDismantleCurve( counter )) 3349 break; 3350 SetCursor(hOldCursor); 3351 return TRUE; 3352 }; 3353 //***************************************************************************** 3354 // Protokoll 3355 //***************************************************************************** 3356 3357 //! klier 01.03.2003 Protokollbuch 3358 //! Speichert Informationen im Protokollbuch 3359 void TAreaScanWindow::SetMeasurementProtocolParameter( void ) 3360 { 3361 TCurve* Report= lpDBase->GetScanReport(); 3362 char buf[ MaxString ]; 3363 3364 if (!IsProtocolDiffractometryOn()) 3365 return; 3366 3367 sprintf(buf, szODF, Report->GetMin( P_X )); 3368 SetProtocolDiffractometryMinimum1(buf); 3369 sprintf(buf, szOWF, dOmegaWidth); 3370 SetProtocolDiffractometrySchrittweite1(buf); 3371 sprintf(buf, szODF, Report->GetMax( P_X )); 3372 SetProtocolDiffractometryMaximum1(buf); 3373 3374 //klier 30.01.2003 Der Wert für das Offset wird mit ausgegeben 3375 sprintf(buf, szODF, mlGetOffset(nOmega)); 3376 SetProtocolDiffractometrySOffset1(buf); 3377 3378 //! in abhaengigkeit von art des Scans haben die Thetaeintraege verschiedene 3379 //! bedeutungen 3380 if (VisualDB.bPsd) 3381 { //! speichern einer Psd-Datenbasis 3382 sprintf(buf, szTDF, Report->GetMin( P_Y ) - dPsdOffset); 3383 SetProtocolDiffractometryMinimum2(buf); 3384 sprintf(buf, szTDF, Report->GetMax( P_Y ) - dPsdOffset); 3385 SetProtocolDiffractometryMaximum2(buf); 3386 if (dThetaMin != dThetaMax) 3387 { 3388 sprintf(buf, szTWF, dOmegaWidth * VisualDB.dMoveRelation); 3389 SetProtocolDiffractometrySchrittweite2(buf); 3390 } 3391 } 3392 else 3393 { //! speichern einer SLD-DatenBasis mit zentren der Thetawindows als Thetawerte 3394 sprintf(buf, szTDF, VisualDB.dThetaMinFirst + 0.5* VisualDB.dThetaWindow); 3395 SetProtocolDiffractometryMinimum2(buf); 3396 sprintf(buf, szTDF, VisualDB.dThetaMinFirst + 0.5*VisualDB.dThetaWindow + (Report->GetPNumber() - 1)* dOmegaWidth * VisualDB.dMoveRelation); 3397 SetProtocolDiffractometryMaximum2(buf); 3398 if (dThetaMin != dThetaMax) 3399 { 3400 sprintf(buf, szTWF, dOmegaWidth * VisualDB.dMoveRelation); 3401 SetProtocolDiffractometrySchrittweite2(buf); 3402 } 3403 } 3404 3405 //klier 30.01.2003 Der Wert für das Offset wird mit ausgegeben 3406 sprintf(buf, szTDF, mlGetOffset(nTheta)); 3407 SetProtocolDiffractometrySOffset2(buf); 3408 3409 MeasurementParameter.GetReflection(buf); 3410 SetProtocolDiffractometryUReflex(buf); 3411 MeasurementParameter.GetOrientation(buf); 3412 SetProtocolDiffractometryOrientierung(buf); 3413 3414 sprintf(buf, "%.3f", MeasurementParameter.GetWaveLength()); 3415 SetProtocolDiffractometryWellenlaenge(buf); 3416 sprintf(buf, "%d", MeasurementParameter.GetCurrent()); 3417 SetProtocolDiffractometryStrom(buf); 3418 sprintf(buf, "%d", MeasurementParameter.GetVoltage()); 3419 SetProtocolDiffractometrySpannung(buf); 3420 }; 3421 //***************************************************************************** 3422 3423 LPCSTR TAreaScanWindow::GetRepFileName() 3424 { 3425 char drive[ _MAX_DRIVE+1 ], path[ _MAX_DIR+1 ], name[ _MAX_FNAME+1 ], ext[ _MAX_EXT+1 ]; 3426 //! ermitteln des Dateinamen + anhaengen der Extension .rep 3427 _splitpath( FileName, drive, path, name, ext ); 3428 _makepath( m_RepFileName, drive, path, name, "rep" ); 3429 return m_RepFileName; 3430 } 3431 //***************************************************************************** 3432 3433 //! Funktion liefert den absoluten Thetawert als Rueckkehrcode 3434 //! 1.Param. scid gibt Kurvennr. an, deren absoluter Thetawert gesucht ist 3435 //! nur bei RL-Bitmap benutzt 3436 double TAreaScanWindow::GetThetaOffset( int scid ) 3437 { 3438 float theta, v; 3439 3440 // this function returns an absolute Theta Value 3441 switch ( eOutputType ) 3442 { 3443 case otReciprokeLatticeBitmap: 3444 //! liefert 0 wenn zuwenig Kurven in Datenbasis sonst den Thetawert der 3445 //! scid-ten Kurve der Datenbasis 3446 if ( 2 > lpDBase->GetCNumber() ) 3447 return 0.0; 3448 3449 ScanReport->SetPP( scid ); 3450 ScanReport->PGet( v, theta, v ); 3451 return theta - dThetaOffset; 3452 3453 case otMatrixBitmap: 3454 //! liefert 0 wenn zuwenig Kurven in Datenbasis sonst den Thetawert der 3455 //! 0-ten Kurve der Datenbasis 3456 if ( 2 > lpDBase->GetCNumber() ) 3457 return 0.0; 3458 3459 //! Aenderung B.Buss ScanReport->SetPP( 0 ); 3460 ScanReport->SetPP( scid ); 3461 ScanReport->PGet( v, theta, v ); 3462 return theta - dThetaOffset; 3463 3464 case otCurve: 3465 //! bei kont.Anzeige den akt. Thetawinkel als Offset zurueck 3466 if ( bShowPsdContinuous ) 3467 return ( mlGetValue( nTheta, Distance ) /*Theta soll relativ sein - mlGetOffset( nTheta )*/ ); 3468 3469 //! wenn kein Psd angeschl. offset=0 3470 //! FIX Fehler 39 3471 if ( VisualDB.bPsd ) 3472 { 3473 //! neu akk 3474 //! waehrend des Scans existiert noch keine reportkurve 3475 //! deshalb akt. motorposition 3476 if ( !bMeasurementActive ) 3477 { 3478 //! Offset= thetawert der letzten Kurve holen wenn dieser gueltig ist 3479 //! sonst 0 3480 ScanReport->SetPP( nActiveScan ); 3481 ScanReport->PGet( v, theta, v ); 3482 if ( ( theta > 1000.0 ) || ( theta < -1000.0 ) ) 3483 return 0.0; 3484 else 3485 return theta; 3486 } else 3487 return ( mlGetValue( nTheta, Distance ) /*Theta soll relativ sein - mlGetOffset( nTheta )*/ + dOffsetTheta ); 3488 } else return 0.0; 3489 3490 default: 3491 MessageBox( szMsgLine023, szMessage, MBINFO ); 3492 return 0.0; 3493 } 3494 }; 3495 //***************************************************************************** 3496 3497 //! bildn. Darstellung ausschl. in TPlotWindow verwendet 3498 BOOL TAreaScanWindow::SetMeasurementArea( TKSystem &ks ) 3499 { 3500 /* 3501 fPsdRange wird fuer jede Messung mit GetPsd()->GetAngleRange() oder nach dem Einlesen in LoadMeasurementInfo() und LoadOldData() gesetzt. 3502 */ 3503 switch ( eOutputType ) 3504 { 3505 case otReciprokeLatticeBitmap: 3506 ks[ 0 ].x= DegToRad ( VisualDB.dThetaMinFirst ); 3507 ks[ 0 ].y= DegToRad ( VisualDB.dOmegaMin ); //! FIX Fehler 39 3508 ks[ 0 ].Ord= 0; 3509 ks[ 1 ].x= DegToRad ( VisualDB.dThetaMaxFirst ); //! FIX Fehler 39 3510 ks[ 1 ].y= DegToRad ( VisualDB.dOmegaMin ); //! FIX Fehler 39 3511 ks[ 1 ].Ord= 1; 3512 ks[ 2 ].x= DegToRad ( VisualDB.dThetaMaxLast ); //! FIX Fehler 39 3513 ks[ 2 ].y= DegToRad ( VisualDB.dOmegaMax ); //! FIX Fehler 39 3514 ks[ 2 ].Ord= 2; 3515 ks[ 3 ].x= DegToRad ( VisualDB.dThetaMinLast ); 3516 ks[ 3 ].y= DegToRad ( VisualDB.dOmegaMax ); //! FIX Fehler 39 3517 ks[ 3 ].Ord= 3; 3518 break; 3519 3520 case otMatrixBitmap: 3521 ks[ 0 ].x= VisualDB.dThetaMinFirst /*0.0*/; 3522 ks[ 0 ].y= VisualDB.dOmegaMin; //! FIX Fehler 39 3523 ks[ 0 ].Ord= 0; 3524 ks[ 1 ].x= VisualDB.dThetaMaxFirst /*fAngleRange*/; //! FIX Fehler 39 3525 ks[ 1 ].y= VisualDB.dOmegaMin; //! FIX Fehler 39 3526 ks[ 1 ].Ord= 1; 3527 //! B.Buss geaendert ks[ 2 ].x= ::fPsdRange; 3528 //! FIX Fehler 39 3529 ks[ 2 ].x= VisualDB.dThetaMaxLast /*GetThetaOffset(lpDBase->GetCNumber()-1)-GetThetaOffset(0) + VisualDB.fAngleRange*/; 3530 ks[ 2 ].y= VisualDB.dOmegaMax; //! FIX Fehler 39 3531 ks[ 2 ].Ord= 2; 3532 ks[ 3 ].x= VisualDB.dThetaMinLast /*0.0*/; 3533 ks[ 3 ].y= VisualDB.dOmegaMax; //! FIX Fehler 39 3534 ks[ 3 ].Ord= 3; 3535 break; 3536 } 3537 return TRUE; 3538 }; 3539