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...";
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 );
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