{ 30.01.05:FO: le style lighting a été désactive                                }
{ les contours plots ne supportent pas les abscisses decroissantes              }
unit Graph4D;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, ComCtrls, Spin, AppEvnts, EditData, EditReal, Menus,
  GR32_RangeBars,math, FileCtrl, JvDriveCtrls, StrUtils, JvComponent,
  JvFormPlace, Buttons, filesIO;

type
  TGraph4DForm = class(TForm)
    StatusBar1: TStatusBar;
    ApplicationEvents1: TApplicationEvents;
    MainMenu1: TMainMenu;
    Graph2D: TMenuItem;
    ReadfromNeXus1: TMenuItem;
    SavetoNeXuS1: TMenuItem;
    Open1: TMenuItem;
    Save2D1: TMenuItem;
    ReadfromPAXY1: TMenuItem;
    SavetoPAXY1: TMenuItem;
    Opration1: TMenuItem;
    Extractselection1: TMenuItem;
    N3: TMenuItem;
    Scalar1: TMenuItem;
    Addition1: TMenuItem;
    Soustraction2: TMenuItem;
    Multiplication1: TMenuItem;
    Division1: TMenuItem;
    Betweenspectra1: TMenuItem;
    Addition2: TMenuItem;
    Soustraction3: TMenuItem;
    Multiplication2: TMenuItem;
    Division2: TMenuItem;
    surmoniteur: TMenuItem;
    N1: TMenuItem;
    Supprimer2D2: TMenuItem;
    Rotation1: TMenuItem;
    Panel8: TPanel;
    Label24: TLabel;
    Panel9: TPanel;
    ChoixSpectre: TComboBox;
    Panel5: TPanel;
    Scale: TPageControl;
    TabSheet4: TTabSheet;
    Label26: TLabel;
    ZminBox: TEditReal;
    ZmaxBox: TEditReal;
    ZlogCheckBox: TCheckBox;
    AutoScaleCheckBox: TCheckBox;
    TabSheet5: TTabSheet;
    palettecombo: TComboBox;
    TabSurface: TTabSheet;
    Panel6: TPanel;
    Panel7: TPanel;
    MiniParserBox: TEdit;
    Label3: TLabel;
    PerspectiveCheckBox: TCheckBox;
    Label1: TLabel;
    Label9: TLabel;
    TabContour: TTabSheet;
    InvertedColor: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox7: TCheckBox;
    ComboStyle: TComboBox;
    ComboFrame: TComboBox;
    Label2: TLabel;
    Label4: TLabel;
    GroupBox4: TGroupBox;
    UpDown2: TUpDown;
    UpDown3: TUpDown;
    Edit1: TEdit;
    Label5: TLabel;
    ContrastBox: TEditReal;
    ScaleBar: TGaugeBar;
    ScaleSy: TGaugeBar;
    ScaleSz: TGaugeBar;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    HeightLine: TEditReal;
    HeightLineCheckBox: TCheckBox;
    FontDialog1: TFontDialog;
    Font1: TMenuItem;
    GetFileButton: TButton;
    FileNrSpinEdit: TSpinEdit;
    FileTypeButton: TButton;
    Help1: TMenuItem;
    MouseCTRLZOOM1: TMenuItem;
    MouseSHIFTCrossSection1: TMenuItem;
    ScaleSyContour: TGaugeBar;
    Label6: TLabel;
    SpeedButton2: TSpeedButton;
    JvFormPlace1: TJvFormPlace;
    PnlPos: TPanel;
    Label7: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Xpos1: TEditReal;
    Xpos2: TEditReal;
    Ypos2: TEditReal;
    Ypos1: TEditReal;
    Zval1: TEditReal;
    Zval2: TEditReal;
    Panel3: TPanel;
    DisplayCursorsCheckBox: TCheckBox;
    PageControl3: TPageControl;
    TabSheet3: TTabSheet;
    TabSheet6: TTabSheet;
    TabSheet7: TTabSheet;
    IOtextBox: TEdit;
    LabelSetButton: TButton;
    SetAsCombo: TComboBox;
    moniteur: TEditReal;
    Label8: TLabel;
    Label13: TLabel;
    sommetotal: TEditReal;
    somme: TEditReal;
    Label12: TLabel;
    GroupBox1: TGroupBox;
    Label14: TLabel;
    Label17: TLabel;
    Xcen: TEditReal;
    Ycen: TEditReal;
    CalculateCircularSumButton: TButton;
    BinningStepBox: TEditReal;
    Panel1: TPanel;
    ParamLabel1: TLabel;
    ParamLabel6: TLabel;
    ParamLabel5: TLabel;
    ParamLabel4: TLabel;
    ParamLabel3: TLabel;
    ParamLabel2: TLabel;
    ParamBox1: TEditReal;
    ParamBox2: TEditReal;
    paramBox3: TEditReal;
    ParamBox4: TEditReal;
    ParamBox5: TEditReal;
    ParamBox6: TEditReal;
    CheckBoxMasks: TCheckBox;
    TypeMaskCombo: TComboBox;
    SymmetryBox: TRadioGroup;
    Label15: TLabel;
    MaskButton: TButton;
    NomMaskEdit: TEdit;
    RotationAngleBox: TEditReal;
    Label23: TLabel;
    Edit2: TMenuItem;
    ReadNeXuSLLB1: TMenuItem;
    Read3columnsfilesXYZ1: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    N8: TMenuItem;
    ReadfreeXYZ1: TMenuItem;
    ReaddatPAXE1: TMenuItem;
    ReadTPAimage1: TMenuItem;
    ReadTPAimage2: TMenuItem;
    ReadfromMatlabASCII1: TMenuItem;
    ReadHADASPSDimage1: TMenuItem;
    ReadLAMPD171: TMenuItem;
    ReadSDMScalculation1: TMenuItem;
    ReadHADASglattaftersmoothing1: TMenuItem;
    SavetoASCII1: TMenuItem;
    Savetobitmap1: TMenuItem;
    Savetobinarysigend32bits1: TMenuItem;
    Read1: TMenuItem;
    Save1: TMenuItem;
    WorkingDirectoryMenu: TMenuItem;
    Copygraph1: TMenuItem;
    Fileformats1: TMenuItem;
    Label16: TLabel;
    Panel4: TPanel;
    Panel2: TPanel;
    Xprojection: TRadioGroup;
    Yprojection: TRadioGroup;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    PaintBoxContour: TPaintBox;
    FileListBox: TJvFileListBox;
    TabSheet2: TTabSheet;
    PaintBoxSurface: TPaintBox;
    ScrollBarGaucheDroite: TScrollBar;
    ScrollBarHautBas: TScrollBar;
    TabSheet8: TTabSheet;
    PaintBox4D: TPaintBox;
    ScrollBar4DV: TScrollBar;
    ScrollBar4DH: TScrollBar;
    IntegrateButton: TButton;
    Panel10: TPanel;
    ChoixSpectre3D: TComboBox;
    Extract3Dbutton: TButton;
    Button2: TButton;
    Label19: TLabel;
    CutStyleBox: TComboBox;
    Panel11: TPanel;
    LTcutproj: TEditReal;
    YcutProj: TEditReal;
    XcutProj: TEditReal;
    XmaxProj: TEditReal;
    YmaxProj: TEditReal;
    ltMaxProj: TEditReal;
    ltMinProj: TEditReal;
    YminProj: TEditReal;
    XminProj: TEditReal;
    Label20: TLabel;
    Label27: TLabel;
    Label25: TLabel;
    Label21: TLabel;
    FlipBox: TCheckBox;
    SpinX: TUpDown;
    SpinY: TUpDown;
    SpinLT: TUpDown;
    ProjectButton: TButton;
    Iso4DBox: TCheckBox;
    IsoValueBox: TEditReal;
    OvFOOMMFascii1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure PaintBoxSurfacePaint(Sender: TObject);
    procedure SpinEdit2Change(Sender: TObject);
    procedure PerspectiveCheckBoxClick(Sender: TObject);
    procedure PaintBoxSurfaceMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBoxSurfaceMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PaintBoxSurfaceMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Image2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure UpDown2Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown3Click(Sender: TObject; Button: TUDBtnType);
    procedure ApplicationEvents1Hint(Sender: TObject);
    procedure MiseAjourChoixSpectre(var ListeDeSpectres:spectList);
    procedure MiseAjourChoixSpectre3D(var ListeDeSpectres:spectList);
    procedure PaintBoxContourPaint(Sender: TObject);
    procedure PaintBoxContourMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBoxContourMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PageControl1Change(Sender: TObject);
    procedure LoadDataButtonClick(Sender: TObject);
    procedure CopyBitmapToClipboard1Click(Sender: TObject);
    procedure ScrollBarHautBasChange(Sender: TObject);
    procedure ComboStyleChange(Sender: TObject);
    procedure ComboFrameChange(Sender: TObject);
    procedure YscaleFactorKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ZscaleFactorKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure CheckBox6KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SetXaxisTitle1Click(Sender: TObject);
    procedure SetYaxisTitle1Click(Sender: TObject);
    procedure SetZaxistitle1Click(Sender: TObject);
    procedure palettecomboChange(Sender: TObject);
    procedure PrintFormClick(Sender: TObject);
    procedure ChoixSpectreChange(Sender: TObject);
    procedure ChoixSpectreDropDown(Sender: TObject);
    procedure ZminBoxKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ZmaxBoxKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SetPlotTitle1Click(Sender: TObject);
    procedure ScaleBarChange(Sender: TObject);
    procedure ScaleSyChange(Sender: TObject);
    procedure ScaleSzChange(Sender: TObject);
    procedure ZlogCheckBoxClick(Sender: TObject);
    Procedure LoadSpectrum(s:string);
    Procedure LoadSpectrum3D(s:string);    
    procedure ReadfromPAXY1Click(Sender: TObject);
    procedure ReadfromNeXus1Click(Sender: TObject);
    procedure Open1Click(Sender: TObject);
    procedure SavetoNeXuS1Click(Sender: TObject);
    procedure Save2D1Click(Sender: TObject);
    procedure SavetoPAXY1Click(Sender: TObject);
    procedure LabelSetButtonClick(Sender: TObject);
    procedure HeightLineCheckBoxClick(Sender: TObject);
    procedure Font1Click(Sender: TObject);
    procedure FileTypeButtonClick(Sender: TObject);
    procedure GetFileButtonClick(Sender: TObject);
    procedure OpenFileNeXus(filename:string);
    procedure OpenFile2D(filename:string);
    procedure OpenFilePAXY(filename:string);
    procedure ScaleSyContourChange(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure PaintBoxContourMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure Extractselection1Click(Sender: TObject);
    procedure Supprimer2D2Click(Sender: TObject);
    procedure Addition1Click(Sender: TObject);
    procedure Soustraction2Click(Sender: TObject);
    procedure Multiplication1Click(Sender: TObject);
    procedure Division1Click(Sender: TObject);
    procedure Addition2Click(Sender: TObject);
    procedure Soustraction3Click(Sender: TObject);
    procedure Multiplication2Click(Sender: TObject);
    procedure Division2Click(Sender: TObject);
    procedure Rotation1Click(Sender: TObject);
    procedure CalculateCircularSumButtonClick(Sender: TObject);
    procedure MaskButtonClick(Sender: TObject);
    procedure ReadNeXuSLLB1Click(Sender: TObject);
    procedure Copygraph1Click(Sender: TObject);
    procedure ReaddatPAXE1Click(Sender: TObject);
    procedure ReadTPAimage2Click(Sender: TObject);
    procedure ReadTPAimage1Click(Sender: TObject);
    procedure Read3columnsfilesXYZ1Click(Sender: TObject);
    procedure ReadfreeXYZ1Click(Sender: TObject);
    procedure ReadfromMatlabASCII1Click(Sender: TObject);
    procedure ReadHADASPSDimage1Click(Sender: TObject);
    procedure ReadHADASglattaftersmoothing1Click(Sender: TObject);
    procedure ReadSDMScalculation1Click(Sender: TObject);
    procedure ReadLAMPD171Click(Sender: TObject);
    procedure SavetoASCII1Click(Sender: TObject);
    procedure Savetobinarysigend32bits1Click(Sender: TObject);
    procedure Savetobitmap1Click(Sender: TObject);
    procedure WorkingDirectoryMenuClick(Sender: TObject);
    procedure AutoScaleCheckBoxClick(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure PaintBox4DPaint(Sender: TObject);
    procedure ScrollBar4DVChange(Sender: TObject);
    procedure ScrollBar4DHChange(Sender: TObject);
    procedure IntegrateButtonClick(Sender: TObject);
    procedure CutStyleBoxChange(Sender: TObject);
    procedure FlipBoxClick(Sender: TObject);
    procedure ChoixSpectre3DChange(Sender: TObject);
    procedure XminProjChange(Sender: TObject);
    procedure YminProjChange(Sender: TObject);
    procedure ltMinProjChange(Sender: TObject);
    procedure XmaxProjChange(Sender: TObject);
    procedure YmaxProjChange(Sender: TObject);
    procedure ltMaxProjChange(Sender: TObject);
    procedure XcutProjChange(Sender: TObject);
    procedure YcutProjChange(Sender: TObject);
    procedure LTcutprojChange(Sender: TObject);
    procedure SpinXClick(Sender: TObject; Button: TUDBtnType);
    procedure SpinYClick(Sender: TObject; Button: TUDBtnType);
    procedure SpinLTClick(Sender: TObject; Button: TUDBtnType);
    procedure Button2Click(Sender: TObject);
    procedure Reset3D;
    procedure Extract3DbuttonClick(Sender: TObject);
    procedure ProjectButtonClick(Sender: TObject);
    procedure Iso4DBoxClick(Sender: TObject);
    procedure IsoValueBoxKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure XminProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure XmaxProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure XcutProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure YmaxProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure YcutProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ltMinProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ltMaxProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure LTcutprojKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure YminProjKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure OvFOOMMFascii1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Graph4DForm: TGraph4DForm;
  X1pos,Y1pos,X2pos,Y2pos:integer; { position des curseurs }
  WorkingDirectory:string;

implementation

{$R *.DFM}

(* This sample program shows a very complicated situation, three separate graphs
   of which one in canvas mode, and the animation made things even worse.
   Making this revealed several bugs in the program and as such it has been
   useful, but you are advised to keep things more simple.
   This program is only intended to show some possibilities of XYGRAPH3D.
   The use of the PRINT&COPY form is explained in the unit XYCopy.pas *)

uses xygraph_emmens, xygraph3d, xygraph4D, xycopy, BoiteNoire,GR32, MainForm,
  dialogScalAddSpectrum, dialogAddSpectrum, LectureTPAoptions;

{ constants for the animation: adjust these to the speed of your computer}
const timerinterval = 1000;   {set timer speed, interval in ms}
      rotationincrement = 10; {set rotation increment in degr}

const colorscheme : array[1..6,0..8] of Tcolor =
  ( ($000000, $804040, $ff8080, $00c000, $00c0c0, $4080a0, $204060, $808080, $FFFFFF), { multicolor }
    ($000000, $000060, $800080, $ff0000, $ff8080, $20ff20, $00ffff, $0080ff, $0000e0), { rainbow }
    ($000000, $000020, $000040, $000060, $000080, $0000A0, $0000C0, $0000E0, $FFFFFF), { black-Red-white }
    ($000000, $200000, $400000, $600000, $800000, $A00000, $C00000, $E00000, $FFFFFF), { black-blue-white }
    ($800000, $A02020, $C06060, $E0A0A0, $FFFFFF, $8080F0, $6060E0, $4040D0, $2020C0), { blue-white-red }
    ($FF0000, $E00000, $C00000, $A00000, $000000, $00A000, $00C000, $00E000, $00FF00) );  { Blue - red }
{    ($000000,HSLtoRGB(0.9,32,32),HSLtoRGB(0.9,64,64),HSLtoRGB(0.9,96,96),HSLtoRGB(0.9,128,128),HSLtoRGB(0.9,160,160),HSLtoRGB(0.9,192,192),HSLtoRGB(0.9,224,224), $FFFFFF) ); } 

{    palGrayscale[i] :=HSLtoRGB(0, 0, f );
    palGreens[i] := HSLtoRGB(f * 0.4, 0.5, f * 0.4 + 0.2);
    palReds[i] := HSLtoRGB(0.8 + f * 0.3 , 0.7 + f * 0.3, f * 0.85 + 0.1);
    palMultiColor[i] := HSLtoRGB(f * 1.2, 0.6, f * 0.8 + 0.2);
    palRainbow[i] := HSLtoRGB(0.9*f, 1, 0.5);
    palBlues[i] := HSLtoRGB(0.7, f, f);
    palPurple[i] := HSLtoRGB(0.9, f, f);
    palCustom[i] := HSLtoRGB(a*f+a2, b*f+b2, c*f+c2); }

var data3D,data3Dlog: Tdatatype;
    hoek1, hoek2, mode1, mode2, cmode : integer;
    lh,lp : integer;
    data0 : array[0..4,1..10] of single;
    plotTitle,xaxisLegend,yaxisLegend,zaxisLegend:string;
    dataZmin,dataZmax:double;
    data4D,data4Dlog: T4dtype;

procedure TGraph4DForm.OpenFileNeXus(filename:string);
var vind,l:integer;
    nom,ext:string;
begin
     nom:=ProcessFileName(filename);
      vind:=deuxd.indexof(nom);
      if vind=-1 then vind:=deuxd.addspectre(nom,1,1,1); {creation avec taille arbitraire, le spectre prendra ensuite la taille du fichier}
      deuxd.spect[vind].ReadFromNexus(filename);
      MiseAjourChoixSpectre(deuxd);
      choixspectre.Text:=nom;
      LoadSpectrum(ChoixSpectre.Text);
end;

procedure TGraph4DForm.OpenFile2D(filename:string);
var vind,l:integer;
    nom:string;
begin
      nom:=ProcessFileName(filename);
      vind:=deuxd.indexof(nom);
      if vind=-1 then vind:=deuxd.addspectre(nom,1,1,1); {creation avec taille arbitraire, le spectre prendra ensuite la taille du fichier}
      deuxd.spect[vind].open(filename);
      MiseAjourChoixSpectre(deuxd);
      choixspectre.Text:=nom;
      LoadSpectrum(ChoixSpectre.Text);
end;

procedure TGraph4DForm.OpenFilePAXY(filename:string);
var titre,date,heure,temps,ext,nomspectre,nom:string;
    vind,l:integer;
begin
   nomSpectre:=ProcessFileName(filename);
   vind:=deuxd.indexof(nomspectre);
   if vind=-1 then vind:=deuxd.addspectre(nomspectre,128,128,1);
   deuxd.spect[vind].readfromPAXY(filename,titre,nom,date,heure,temps);
   MiseAjourChoixSpectre(deuxd);
   choixspectre.Text:=nomspectre;
   LoadSpectrum(ChoixSpectre.Text);
end;


{ mise a jour de la combo ChoixSpectre à partir de la liste des spectres 2D }
{ INPUT: la liste de spectres "deuxd" en général                            }
{        a passer en var parce que la taille risque de devenir gigantesque  }
procedure TGraph4DForm.MiseAjourChoixSpectre(var ListeDeSpectres:spectList);
var i:integer;
begin
{reinitialisation des items a chaque ouverture du combo}
   choixSpectre.items.clear;
   for i:=1 to totalspectre do
   begin
      if ListeDeSpectres<>nil then
      if deuxd.spect[i]<>nil then
      choixSpectre.items.add(ListeDeSpectres.spect[i].nom);
   end;
end;

{ mise a jour de la combo ChoixSpectre à partir de la liste des spectres 2D }
{ INPUT: la liste de spectres "deuxd" en général                            }
{        a passer en var parce que la taille risque de devenir gigantesque  }
procedure TGraph4DForm.MiseAjourChoixSpectre3D(var ListeDeSpectres:spectList);
var i:integer;
begin
{reinitialisation des items a chaque ouverture du combo}
   choixSpectre3D.items.clear;
   for i:=1 to totalspectre do
   begin
      if ListeDeSpectres<>nil then
      if troisd.spect[i]<>nil then
      choixSpectre3D.items.add(ListeDeSpectres.spect[i].nom);
   end;
end;


{ plot de la surface avec des axes }
procedure TGraph4DForm.PaintBoxSurfacePaint(Sender: TObject); {XXXXXXXXXXXXXXXXXXXXXXXXXXXX}
const backcol = $000050;
var x,y,sy,wi,hoek1,hoek2,TailleX,TailleY : integer;
    t,d : single;
    Sz,xmin,xmax,ymin,ymax:double;
    ok : boolean;
begin
  wi := paintboxSurface.width;
  { perspective }
  if PerspectiveCheckbox.checked then d := 5 else d := 0;
  hoek1 := scrollbarGaucheDroite.position;
  hoek2 := scrollbarHautBas.position;

  xycleargraph(paintboxSurface,clWhite,clWhite,1.0);
  xystartgraph(0,100,0,100,20,20,20,20,clipon);
  TailleX:=length(data3D);TailleY:=length(data3D[0]);
  xmin:=data3D[1,0];xmax:=data3D[tailleX-1,0];ymin:=data3D[0,1];ymax:=data3D[0,tailleY-1];
  if AutoScaleCheckBox.checked=true
  then begin zminbox.value:=dataZmin;zmaxbox.value:=dataZmax end;
  Sz:=(xmax-xmin)/(dataZmax-dataZmin)*ScaleSz.Position/10;

  xy3dsetframe(xmin,xmax,ymin,ymax,zminbox.value,zmaxbox.value,ScaleSY.position/10,Sz,ScaleBar.position / 100,0);
  xy3dsetlabels(XaxisLegend,YaxisLegend,ZaxisLegend,'','','',true,2,2,2,0,6);
  xytitle(clblack,PlotTitle);
  xy3dsetview(hoek1,hoek2,d,0);
  xy3dshowframe(ComboFrame.itemIndex,clblack,clwhite,clwhite,clwhite,0);
  xy3dsettransmode(1,0,0);
  if ZlogCheckBox.checked=false then xy3dloadsurface(data3D,ok,0,0) else xy3dloadsurface(data3Dlog,ok,0,0);

  { il faut placer cette ligne ici parce que load surface met une echelle de gris }
  if (cmode>0) then xy3dsetcolors(colorscheme[cmode]);
  xy3dsetsun(lp,lh,contrastBox.value,1);
  xy3dshowsurface(ComboStyle.itemindex,0,clblack,clred,clred,false,true,1,8+4);
  xypen.color := clblack;
  xysetlinestyle(0,0,0);
  xy3dcloseframe;
  with paintboxSurface do xyinitruler(clblack,width-4,height-xycharheight-2,-1);
  xyputbuffer(1);

{ Autre version 3D}
{  if checkbox6.checked then d := 0.12 else d := 0;
   picture.bitmap.height := height; picture.bitmap.width := width;
   xycanvasgraph(canvas,width,height,backcol,0,1,true);
   if checkbox1.checked then xy3dshowframe(2,clyellow,-1,-1,-1,3);
   xy3dshowsurface(mode1,d,clwhite,clblack,clwhite, checkbox5.checked,spliton,0,0);
   s := inttostr(hoek1)+' / '+inttostr(hoek2);
   xybrush.color := backcol;
   xytext(clwhite,s,0,0,1,1,0); }
end;

{ tracé du plot de type contour }
procedure TGraph4DForm.PaintBoxContourPaint(Sender: TObject);
var ok : boolean;
    i,grcol,wi,he,opt : integer;
    Yscale:double;
begin
{  PaintBoxContour.Font:=FontDialog1.font; }
  if ZlogCheckBox.checked then opt:=8 else opt:=0;
  with Graph4DForm do begin
   wi := paintboxContour.width; he := paintboxContour.height;
   xycleargraph(paintboxContour,clWhite,clWhite,0.9);
   xystartgraph(5,95,5,95,20,35,5,20,false);
   xy3dloadsurface(data3D,ok,0,1);
   xy3dsetsun(lp,lh,contrastBox.value,1); grcol := clBlack;
{   xy3dsetlabels(XaxisLegend,YaxisLegend,ZaxisLegend,'','','',1,1,1,true);
   xytitle(clblack,'Mon titre'); }
{   case mode2 of }
{   2,3 : }begin
        if (cmode>0) then xy3dsetcolors(colorscheme[cmode]);
        if ScaleSyContour.position>=0 then Yscale:=1+ScaleSyContour.position/11
                                      else Yscale:=1+ScaleSyContour.position/51;
        if AutoScaleCheckBox.Checked=true
        then xy3dshowcontour(3,clBlack,$fff0f0,XaxisLegend,YaxisLegend,Yscale,0,0,1.5,0,1,InvertedColor.checked,splitoff,checkbox7.checked,dummy,3+opt)
        else xy3dshowcontour(3,clBlack,$fff0f0,XaxisLegend,YaxisLegend,Yscale,zminBox.value,zmaxBox.value,1.5,0,1,InvertedColor.checked,splitoff,checkbox7.checked,dummy,3+opt);
        xy3dheightscale(wi-30,30,wi-22,he-20,'Intensity',0);
        if HeightLineCheckBox.checked=true then xy3DheightLine(HeightLine.value,clBlack,0);
        end;
{   4,5 :begin
        if AutoScaleCheckBox.Checked=true
        then xy3dshowcontour(mode2,clwhite,$fff0f0,XaxisLegend,YaxisLegend,0,0,0,1.5,0,NrColors.value,normal,spliton,checkbox7.checked,dummy,3+opt)
        else xy3dshowcontour(mode2,clwhite,$fff0f0,XaxisLegend,YaxisLegend,0,zminBox.value,zmaxBox.value,1.5,0,16,normal,spliton,checkbox7.checked,dummy,3+opt);
        xy3dheightscale(wi-30,30,wi-22,he-20,'height',0);
        end;  }
{   end; }
   if checkbox2.checked then xy3dshowgrid(grcol,0,0);
  end;
  xy3dinitruler(-1,80,1,0);
  xyputbuffer(2);
end;

procedure setlight;
begin
  if (lp>=360) then dec(lp,360);
  if (lp<0) then inc(lp,360);
  Graph4Dform.Edit1.text := inttostr(lp)+' / '+inttostr(lh);
  if (mode2>2) then begin Graph4Dform.paintboxContour.refresh;Graph4Dform.paintboxSurface.refresh; end;
end;


{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}

procedure TGraph4DForm.FormCreate(Sender: TObject);
const l2 = 9; n2 = l2*2; f = 1.5;
var i,j,n,x,y,z: integer;
    ind,tailleX,tailleY:integer;
begin
  windowState:=wsMinimized;
  top:=0;left:=0;width:=523;height:=447;
  MiseAjourChoixSpectre(deuxd);
  MiseAjourChoixSpectre3D(troisd);
{ positionnement par défaut de la fénétre }
  left:=521;top:=0;width:=495;height:=670;
  hoek1 := 0; mode1 := 6;
  hoek2 := 110;
  mode2 := 2; { mode d'affichage du contour }
  cmode := 2; { color mode }
  updown2.position := 0;
  updown3.position := 0;
  PerspectiveCheckbox.checked := true;
  lh := 0; lp := 105; setlight;
  xaxisLegend:='X-axis';yaxisLegend:='Y-axis';zaxisLegend:='Z-axis';
  plotTitle:='My plot';

  TabSurface.Tabvisible:=false;TabContour.Tabvisible:=true;
  randomize;
  { chragement des data des plots par défaut }
  LoadSpectrum(ChoixSpectre.Text);
  LoadSpectrum3D(ChoixSpectre3D.Text);

  x1pos:=999;y1pos:=999;
  x2pos:=999;y2pos:=999;
end;

{ Application.OnHint := DisplayHint;
  hoek1 := 0; mode1 := 6;
  hoek2 := 110; mode2 := 4;
  cmode := 0;
  updown2.position := 0;
  updown3.position := 0;
  spinedit7.value := mode1;
  spinedit8.value := mode2;
  button3.enabled := false;
  radiogroup1.itemindex := 1;
  radiogroup2.itemindex := 0;
  scrollbar1.position := 3;
  checkbox4.checked := true;
  checkbox5.checked := false;
  lh := 0; lp := 105; setlight;
  timer1.interval := timerinterval;

  xy3dsetdataarray(data1,n2-1,n2-1);
  for i := 1 to l2 do
    begin data1[i,0] := -dataA[l2+1-i]; data1[i+l2-1,0] := dataA[i]; end;
  for i := 1 to n2-1 do data1[0,i] := data1[i,0];
  for i := 1 to n2-1 do for j := 1 to n2-1 do
     data1[i,j] := exp(-(sqr(data1[i,0])+sqr(data1[0,j])*2));
  data1[0,0] := data1[5,5];

  xy3dsetdataarray(data2,5,5);
  for i := 0 to 5 do for j := 0 to 5 do data2[i,j] := dataB[i,j];

  randomize;
  for i := 1 to 4 do for j := 1 to 10 do
    data0[i,j] := i*1.5 + random * 1.5;
  for j := 1 to 10 do data0[0,j] := 1 + random * 1;

  xy3dsetdataarray(data3,10,2);
  for j := 1 to 2 do for i := 1 to 10 do data3[i,j] := data0[4,i];

end; }


{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}

procedure TGraph4DForm.FormActivate(Sender: TObject);
begin setlight; end;

procedure TGraph4DForm.CheckBox2Click(Sender: TObject);
begin paintboxContour.refresh; end;

procedure TGraph4DForm.SpinEdit1Change(Sender: TObject);
begin paintboxContour.refresh;  end;


procedure TGraph4DForm.Button3Click(Sender: TObject);
begin cmode := (cmode + 1) mod 3; paintboxContour.refresh; end;

procedure TGraph4DForm.SpinEdit2Change(Sender: TObject);
begin paintboxSurface.refresh; end;

procedure TGraph4DForm.PerspectiveCheckBoxClick(Sender: TObject);
begin paintboxSurface.refresh; end;


{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
{ CONTOUR       }

procedure TGraph4DForm.PaintBoxContourMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 PaintBoxContour.canvas.Pen.color:=clRed;
 PaintBoxContour.canvas.Pen.Mode:=pmNot;
 if (button=mbleft)
 then begin
      if (X1pos<>999) and (Y1pos<>999)
      then begin
           xymove(XYgraphData[1].x1,Y1pos);xydraw(XYgraphData[1].x2,Y1pos);
           xymove(X1pos,XYgraphData[1].y1);xydraw(X1pos,XYgraphData[1].y2); end
      end;
 if (button=mbright)
 then begin
      if (X2pos<>999) and (Y2pos<>999)
      then begin
           xymove(XYgraphData[1].x1,Y2pos);xydraw(XYgraphData[1].x2,Y2pos);
           xymove(X2pos,XYgraphData[1].y1);xydraw(X2pos,XYgraphData[1].y2); end
      end;

 xysetlinestyle(0,0,0);xygetbuffer(2);
{ xymousedown(button,shift,x,y); }
 xymousedown(mbLeft,shift,x,y);
end;

procedure TGraph4DForm.PaintBoxContourMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
var i,n,ind,vind:integer;
begin
  vind:=deuxd.indexof(choixSpectre.text);
{  xymouseup(button,shift,x,y);}
 xymouseup(mbLeft,shift,x,y);
 if (button=mbleft) then
  if (ssshift in shift)
  then { on stocke la cross-section }
       begin
       n := length(xy3dcrosssection);
       if (n<2) then exit;
       ind:=und.addspectre('CS',n,1,1);
       for i:=0 to n-1 do
          begin
          und.spect[ind].data[i,0,0].x:=xy3Dcrosssection[i].L;
          und.spect[ind].data[i,0,0].z:=xy3Dcrosssection[i].Z;
          end;
       end;

 PaintBoxContour.canvas.Pen.color:=clRed;
 PaintBoxContour.canvas.Pen.Mode:=pmNot;
 xymove(XYgraphData[1].x1,Y);xydraw(XYgraphData[1].x2,Y);
 xymove(X,XYgraphData[1].y1);xydraw(X,XYgraphData[1].y2);

 if (button=mbleft)
 then begin
      X1pos:=X;Y1pos:=Y;
      Xpos1.value:=XYExportA.xw;Ypos1.value:=XYExportA.yw[1];
      { stockage des coupes dans les spectres 1D prédéfinis pour affichage dans la fenetre 1D }
      unD.add(deuxd.spect[vind].CoupeHSpectre2D('C1H',Ypos1.value));
      unD.add(deuxd.spect[vind].CoupeVSpectre2D('C1V',Xpos1.value));
      unD.spect[unD.indexof('C1H')].typeX:=deuxd.spect[vind].typeX;
      unD.spect[unD.indexof('C1V')].typeX:=deuxd.spect[vind].typeY;
      end;
 if (button=mbright)
 then begin
      X2pos:=X;Y2pos:=Y;
      Xpos2.value:=XYExportA.xw;Ypos2.value:=XYExportA.yw[1];
      { stockage des coupes dans les spectres 1D prédéfinis pour affichage dans la fenetre 1D }
      unD.add(deuxd.spect[vind].CoupeHSpectre2D('C2H',Ypos2.value));
      unD.add(deuxd.spect[vind].CoupeVSpectre2D('C2V',Xpos2.value));
      unD.spect[unD.indexof('C2H')].typeX:=deuxd.spect[vind].typeX;
      unD.spect[unD.indexof('C2V')].typeX:=deuxd.spect[vind].typeY;
      end;
 unD.add(deuxd.spect[vind].ProjectionHSpectre2D('PV',min(Xpos1.value,Xpos2.value),max(Xpos1.value,Xpos2.value)));
 unD.add(deuxd.spect[vind].ProjectionVSpectre2D('PH',min(Ypos1.value,Ypos2.value),max(Ypos1.value,Ypos2.value)));
 somme.value:=deuxd.spect[vind].IntegraleSpectre2D(min(Xpos1.value,Xpos2.value),min(Ypos1.value,Ypos2.value),max(Xpos1.value,Xpos2.value),max(Ypos1.value,Ypos2.value));
 unD.spect[unD.indexof('PH')].typeX:=deuxd.spect[vind].typeY;
 unD.spect[unD.indexof('PV')].typeX:=deuxd.spect[vind].typeX;

 sendmessage(principalform.handle,wm_redessine,0,0);
end;

{ SURFACE }
procedure TGraph4DForm.PaintBoxSurfaceMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  xysetlinestyle(0,0,0);
  xygetbuffer(1); xymousedown(button,shift,x,y);
end;

procedure TGraph4DForm.PaintBoxSurfaceMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  xymousemove(shift,x,y);
end;

procedure TGraph4DForm.PaintBoxSurfaceMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
  xymouseup(button,shift,x,y);
end;
{ MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM }

procedure TGraph4DForm.Image2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin xygetbuffer(2); xymousedown(button,shift,x,y); end;

procedure TGraph4DForm.UpDown2Click(Sender: TObject; Button: TUDBtnType);
begin
  if (button=btnext) then lp := lp + 5 else lp := lp - 5;
  setlight;
  paintboxSurface.refresh;
end;

procedure TGraph4DForm.UpDown3Click(Sender: TObject; Button: TUDBtnType);
begin
  if (button=btnext) and (lh<90) then  begin lh := lh + 5; setlight; end;
  if (button=btprev) and (lh>-90) then begin lh := lh - 5; setlight; end;
  paintboxSurface.refresh;
end;

procedure TGraph4DForm.ApplicationEvents1Hint(Sender: TObject);
begin statusbar1.simpletext := application.hint; end;

procedure TGraph4DForm.PageControl1Change(Sender: TObject);
begin
  xyclearbuffer;
  if PageControl1.TabIndex=0 then begin TabSurface.Tabvisible:=false;TabContour.Tabvisible:=true; end;
  if PageControl1.TabIndex=1 then begin TabSurface.Tabvisible:=true;TabContour.Tabvisible:=false; end;
end;

procedure TGraph4DForm.LoadDataButtonClick(Sender: TObject);
var i,j,ind,tailleX,tailleY:integer;
begin
  { on definit les limites du plot }
  ind:=deuxd.indexof(ChoixSpectre.Text);
  tailleX:=deuxd.spect[ind].X;tailleY:=deuxd.spect[ind].Y;

  xy3dsetdataarray(data3D,tailleX,tailleY);
  { initialisation des abscisses et es ordonnées }
  for i:=1 to TailleX do data3D[i,0]:=deuxd.spect[ind].data[i-1,0,0].X;
  for j:=1 to TailleY do data3D[0,j]:=deuxd.spect[ind].data[0,j-1,0].Y;
  for i:=1 to TailleX do
     for j:=1 to TailleY do
        data3D[i,j]:=deuxd.spect[ind].data[i-1,j-1,0].Z;
end;

procedure TGraph4DForm.CopyBitmapToClipboard1Click(Sender: TObject);
begin
xycopystart
end;

procedure TGraph4DForm.ScrollBarHautBasChange(Sender: TObject);
begin
paintboxSurface.refresh;
end;

procedure TGraph4DForm.ComboStyleChange(Sender: TObject);
begin paintboxSurface.refresh;end;

procedure TGraph4DForm.ComboFrameChange(Sender: TObject);
begin paintboxSurface.refresh; end;

procedure TGraph4DForm.YscaleFactorKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin   if key=13 then paintboxSurface.refresh; end;

procedure TGraph4DForm.ZscaleFactorKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
   if key=13 then paintboxSurface.refresh;
end;

procedure TGraph4DForm.CheckBox6KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin    paintboxSurface.refresh; end;

procedure TGraph4DForm.SetXaxisTitle1Click(Sender: TObject);
begin
  xaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;
end;

procedure TGraph4DForm.SetYaxisTitle1Click(Sender: TObject);
begin
  yaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;
end;

procedure TGraph4DForm.SetZaxistitle1Click(Sender: TObject);
begin
  zaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;
end;

procedure TGraph4DForm.palettecomboChange(Sender: TObject);
begin
   cmode := palettecombo.itemindex;
   paintboxContour.refresh;
   paintboxsurface.refresh
end;

procedure TGraph4DForm.PrintFormClick(Sender: TObject);
begin
  xycopystart;
end;

{ chargeent d'un spectre 2D dans la variable data3D pour affichage }
{ INPUT : le nom du spectre à charger                           }
{ OUTPUT : on manipule le spectre correspondant                 }
Procedure TGraph4DForm.LoadSpectrum(s:string);
var i,j,ind,tailleX,tailleY:integer;
    Zlog:boolean;
    aux:double;
begin
  dataZmin:=1e32;dataZmax:=-1e32;
  if ZlogCheckBox.checked=false then Zlog:=false;
  { on definit les limites du plot }
  ind:=deuxd.indexof(s);
  tailleX:=deuxd.spect[ind].X;tailleY:=deuxd.spect[ind].Y;
  xy3dsetdataarray(data3D,tailleX,tailleY);
  xy3dsetdataarray(data3Dlog,tailleX,tailleY);
  { initialisation des abscisses et des ordonnées }
  for i:=1 to TailleX do begin data3D[i,0]:=deuxd.spect[ind].data[i-1,0,0].X;data3Dlog[i,0]:=deuxd.spect[ind].data[i-1,0,0].X; end;
  for j:=1 to TailleY do begin data3D[0,j]:=deuxd.spect[ind].data[0,j-1,0].Y;data3Dlog[0,j]:=deuxd.spect[ind].data[0,j-1,0].Y; end;
  for i:=1 to TailleX do
     for j:=1 to TailleY do
        begin aux:=deuxd.spect[ind].data[i-1,j-1,0].Z;
              if aux>dataZmax then dataZmax:=aux;
              if aux<dataZmin then dataZmin:=aux;
              data3Dlog[i,j]:=log10(aux);
              data3D[i,j]:=aux; end;
  paintboxSurface.refresh;
  paintboxContour.refresh;
end;

{ chargeent d'un spectre 3D dans la variable data3D pour affichage }
{ INPUT : le nom du spectre à charger                           }
{ OUTPUT : on manipule le spectre correspondant                 }
Procedure TGraph4DForm.LoadSpectrum3D(s:string);
var i,j,k,ind,tailleX,tailleY,tailleLT:integer;
    Zlog:boolean;
    aux:double;
begin
  dataZmin:=1e32;dataZmax:=-1e32;
  if ZlogCheckBox.checked=false then Zlog:=false;
  { on definit les limites du plot }
  ind:=troisd.indexof(s);
  tailleX:=troisd.spect[ind].X;tailleY:=troisd.spect[ind].Y;tailleLT:=troisd.spect[ind].LT;

  xy4dsetarray(data4D,tailleX,tailleY,tailleLT);
  xy4dsetarray(data4Dlog,tailleX,tailleY,tailleLT);
  { initialisation des abscisses et des ordonnées }
  for i:=1 to TailleX do begin data4D[i,0,0]:=troisd.spect[ind].data[i-1,0,0].X;data4Dlog[i,0,0]:=troisd.spect[ind].data[i-1,0,0].X; end;
  for j:=1 to TailleY do begin data4D[0,j,0]:=troisd.spect[ind].data[0,j-1,0].Y;data4Dlog[0,j,0]:=troisd.spect[ind].data[0,j-1,0].Y; end;
  for k:=1 to TailleLT do begin data4D[0,0,k]:=troisd.spect[ind].data[0,0,k-1].LT;data4Dlog[0,0,k]:=troisd.spect[ind].data[0,0,k-1].LT; end;
  for i:=1 to TailleX do
   for j:=1 to TailleY do
    for k:=1 to TailleLT do
       begin aux:=troisd.spect[ind].data[i-1,j-1,k-1].Z;
       if aux>dataZmax then dataZmax:=aux;
       if aux<dataZmin then dataZmin:=aux;
       data4Dlog[i,j,k]:=log10(aux);
       data4D[i,j,k]:=aux; end;
  paintbox4D.refresh;
end;

procedure TGraph4DForm.ChoixSpectreChange(Sender: TObject);
var i,j,ind,tailleX,tailleY:integer;
    Zlog:boolean;
begin
  { reset des curseurs }
  x1pos:=999;y1pos:=999;
  x2pos:=999;y2pos:=999;

  LoadSpectrum(ChoixSpectre.Text);
end;

procedure TGraph4DForm.ChoixSpectreDropDown(Sender: TObject);
begin
if sender=choixspectre then MiseAjourChoixSpectre(deuxd);
end;

procedure TGraph4DForm.ZminBoxKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin
if key=13 then begin paintboxSurface.refresh; paintboxContour.refresh; end;
end;

procedure TGraph4DForm.ZmaxBoxKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin
if key=13 then begin paintboxSurface.refresh; paintboxContour.refresh; end;
end;

procedure TGraph4DForm.SetPlotTitle1Click(Sender: TObject);
begin
  xytitle(clBlack,IOtextBox.Text);paintboxSurface.refresh;
end;

procedure TGraph4DForm.ScaleBarChange(Sender: TObject);
begin
   paintboxSurface.refresh;
end;

procedure TGraph4DForm.ScaleSyChange(Sender: TObject);
begin
   paintboxSurface.refresh;
end;

procedure TGraph4DForm.ScaleSzChange(Sender: TObject);
begin
paintboxSurface.refresh;
end;

procedure TGraph4DForm.ZlogCheckBoxClick(Sender: TObject);
begin
   LoadSpectrum(ChoixSpectre.text);
end;

procedure TGraph4DForm.ReadfromPAXY1Click(Sender: TObject);
var titre,date,heure,temps,ext,nomspectre,nom:string;
    vind,l:integer;
begin
opendialog1.initialDir:=boitnoir.RepertoireManip.text;
opendialog1.defaultExt:='*.dat';
opendialog1.filter:='*.dat|*.dat';
if opendialog1.execute then
   begin
   {extraction de l'extension}
   nomSpectre:=ProcessFileName(opendialog1.filename);
   vind:=deuxd.indexof(nomspectre);
   if vind=-1 then vind:=deuxd.addspectre(nomspectre,128,128,1);
   deuxd.spect[vind].readfromPAXY(opendialog1.filename,titre,nom,date,heure,temps);
   MiseAjourChoixSpectre(deuxd);
   choixspectre.Text:=nomspectre;
   LoadSpectrum(ChoixSpectre.Text);
   end;
end;

procedure TGraph4DForm.ReadfromNeXus1Click(Sender: TObject);
var vind,l:integer;
    nom,ext:string;
begin
  opendialog1.initialDir:=boitnoir.RepertoireManip.text;
  opendialog1.defaultExt:='*.nxs';
  opendialog1.filter:='*.nxs|*.nxs';
  if opendialog1.execute
  then begin {le spectre est un spectre 2D}
     {extraction de l'extension}
     nom:=ProcessFileName(opendialog1.filename);
      vind:=deuxd.indexof(nom);
      if vind=-1 then vind:=deuxd.addspectre(nom,1,1,1); {creation avec taille arbitraire, le spectre prendra ensuite la taille du fichier}
      deuxd.spect[vind].ReadFromNexus(opendialog1.filename);
      MiseAjourChoixSpectre(deuxd);
      choixspectre.Text:=nom;
      LoadSpectrum(ChoixSpectre.Text);
      end;
end;

procedure TGraph4DForm.Open1Click(Sender: TObject);
var vind,l:integer;
    nom:string;
begin
{  opendialog1.initialDir:=boitnoir.RepertoireManip.text; }
  opendialog1.defaultExt:='*.2D*|*.3D*';
  opendialog1.filter:='Fichiers 2D (*.2Du, *.2Dd)|*.2D*';
  if opendialog1.execute then
   begin
      {extraction de l'extension}
      nom:=ProcessFileName(opendialog1.filename);
      vind:=deuxd.indexof(nom);
      if vind=-1 then vind:=deuxd.addspectre(nom,1,1,1); {creation avec taille arbitraire, le spectre prendra ensuite la taille du fichier}
      deuxd.spect[vind].open(opendialog1.filename);
      MiseAjourChoixSpectre(deuxd);
      choixspectre.Text:=nom;
      LoadSpectrum(ChoixSpectre.Text);
   end;
end;

procedure TGraph4DForm.SavetoNeXuS1Click(Sender: TObject);
var vind:integer;
begin
 vind:=deuxd.indexof(choixSPectre.text);
 if vind>0 then
 begin
 savedialog1.initialDir:=boitnoir.RepertoireManip.text;
 savedialog1.defaultExt:='*.nxs';
 savedialog1.filter:='*.nxs|*.nxs';
 savedialog1.filename:=choixSPectre.text;
 if savedialog1.execute then
    if fileExists(savedialog1.filename)
    then MessageDlg('The file already exists',mtWarning,[mbOk],0)
    else deuxd.spect[vind].saveToNexus(savedialog1.filename);
 end;
end;

procedure TGraph4DForm.Save2D1Click(Sender: TObject);
var vind:integer;
begin
 vind:=deuxd.indexof(choixSPectre.text);
 if vind>0 then
 begin
{ savedialog1.initialDir:=boitnoir.RepertoireManip.text; }
 savedialog1.defaultext:='*.2D';
 savedialog1.filter:='*.2D|*.2D';
 savedialog1.filename:=choixSPectre.text;
 if savedialog1.execute then
    deuxd.spect[vind].save(savedialog1.filename);
 end;
end;

procedure TGraph4DForm.SavetoPAXY1Click(Sender: TObject);
var vind:integer;
begin
   vind:=deuxd.indexof(choixSpectre.text);
   savedialog1.initialDir:=boitnoir.RepertoireManip.text;
   savedialog1.defaultExt:='*.dat';
   savedialog1.filter:='*.dat|*.dat';
   if savedialog1.execute then
     deuxd.spect[vind].savetoPAXYfree(savedialog1.filename);
end;

procedure TGraph4DForm.LabelSetButtonClick(Sender: TObject);
begin
  case SetAsCombo.ItemIndex of
     0:begin xaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;paintboxContour.refresh; end;
     1:begin yaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;paintboxContour.refresh; end;
     2:begin zaxisLegend:=IOtextBox.Text;paintboxSurface.refresh;paintboxContour.refresh; end;
     3:begin xytitle(clBlack,IOtextBox.Text);paintboxSurface.refresh;paintboxContour.refresh; end;
  end;
end;

procedure TGraph4DForm.HeightLineCheckBoxClick(Sender: TObject);
begin paintboxContour.refresh; end;

procedure TGraph4DForm.Font1Click(Sender: TObject);
begin
  FontDialog1.Execute;
end;

procedure TGraph4DForm.FileTypeButtonClick(Sender: TObject);
begin
   if FileTypeButton.caption='.2D' then FileTypeButton.caption:='.nxs'
   else if FileTypeButton.caption='.nxs' then FileTypeButton.caption:='.dat'
        else if FileTypeButton.caption='.dat' then FileTypeButton.caption:='.2D';
end;

procedure TGraph4DForm.GetFileButtonClick(Sender: TObject);
var i,imax:integer;
    s,s1,FileNr,directory:string;
    FileFOund:boolean;
begin
   FileFound:=false;
   FileNr:=IntToStr(FileNrSpinEdit.Value);
{   directory:=boitnoir.RepertoireManip.text; }
   directory:=WorkingDirectory;
   FileListBox.Directory:=directory;
   imax:=FileListBox.Items.Count;
   for i:=0 to imax do
   begin
      s:=FileListBox.Items[i];
      if AnsiContainsStr(s,FileNr)
      then begin
           FileFound:=true;
           { ouverture du fichier proprement dite }
           s1:=directory+'\'+s;
           if FileTypeButton.caption='.2D' then openFile2D(s1);
           if FileTypeButton.caption='.nxs' then openFileNexus(s1);
           if FileTypeButton.caption='.dat' then openFilePAXY(s1);
           break;
           end;
   end;
   If not FileFound then MessageDlg('File not Found', mtInformation,[mbOk], 0);
end;

procedure TGraph4DForm.ScaleSyContourChange(Sender: TObject);
begin
paintboxContour.refresh;
end;

procedure TGraph4DForm.SpeedButton2Click(Sender: TObject);
begin
  X1pos:=999;Y1pos:=999;X2pos:=999;Y2pos:=999;
  LoadSpectrum(ChoixSpectre.Text);
  LoadSpectrum3D(ChoixSpectre3D.Text);
end;

procedure TGraph4DForm.PaintBoxContourMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  xymousemove(shift,x,y);
end;


{ extraction de la zone sélectionnnée sur le graph par les deux curseurs }
procedure TGraph4DForm.Extractselection1Click(Sender: TObject);
var i,j:integer;
    tailleX1,tailleY1,tailleX2,tailleY2,idx1,idx2:integer;
    xmin1,xmax1,ymin1,ymax1,xstep1,ystep1,xaux,yaux,zaux:double;
    xmin_e,xmax_e,ymin_e,ymax_e,x1,x2,y1,y2:double;
begin
       { soit a determiner la taille du spectre de sortie }
       idx1:=deuxd.indexof(choixSpectre.text);
       tailleX1:=deuxd.spect[idx1].X;tailleY1:=deuxd.spect[idx1].Y;
       Xmin1:=min(deuxd.spect[idx1].data[0,0,0].X,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].X);
       Xmax1:=max(deuxd.spect[idx1].data[0,0,0].X,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].X);
       Ymin1:=min(deuxd.spect[idx1].data[0,0,0].Y,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].Y);
       Ymax1:=max(deuxd.spect[idx1].data[0,0,0].Y,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].Y);
       Xstep1:=(Xmax1-Xmin1)/(tailleX1-1);Ystep1:=(Ymax1-Ymin1)/(tailleY1-1);
       { creation du nouveau spectre } { on détermine les poinsts extremes }
       X1:=deuxd.spect[idx1].data[trunc((Xpos1.value-Xmin1)/Xstep1),0,0].X;
       Y1:=deuxd.spect[idx1].data[0,trunc((Ypos1.value-Ymin1)/Ystep1),0].Y;
       X2:=deuxd.spect[idx1].data[trunc((Xpos2.value-Xmin1)/Xstep1)+1,0,0].X;
       Y2:=deuxd.spect[idx1].data[0,trunc((Ypos2.value-Ymin1)/Ystep1)+1,0].Y;
       xmin_e:=min(X1,X2);xmax_e:=max(X1,X2);
       ymin_e:=min(Y1,Y2);ymax_e:=max(Y1,Y2);
       tailleX2:=round((xmax_e-xmin_e)/XStep1+1);
       tailleY2:=round((ymax_e-ymin_e)/YStep1+1);
       { determination de la taille du nouveau spectre et initialisation }
       idx2:=deuxd.addSpectre(choixSpectre.text+'_e',TailleX2,TailleY2,1);
       deuxd.spect[idx2].typeX:=deuxd.spect[idx1].typeX;deuxd.spect[idx2].typeY:=deuxd.spect[idx1].typeY;
       { remplissage du nouveau spectre }
       { scan du premier spectre }
       for i:=0 to TailleX1-1 do
        for j:=0 to TailleY1-1 do
          begin
            xaux:=deuxd.spect[idx1].data[i,j,0].x;
            yaux:=deuxd.spect[idx1].data[i,j,0].y;
            zaux:=deuxd.spect[idx1].data[i,j,0].z;
            if (xaux>=xmin_e) and (xaux<=xmax_e) and (yaux>=ymin_e) and (yaux<=ymax_e) then
            begin
            deuxd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),0].X:=xaux;
            deuxd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),0].Y:=yaux;
            deuxd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),0].Z:=zaux;
            end;
          end;
    x1pos:=999;y1pos:=999;
    x2pos:=999;y2pos:=999;
end;


procedure TGraph4DForm.Supprimer2D2Click(Sender: TObject);
var i,vind:integer;
begin
  vind:=deuxd.indexof(choixSpectre.text);
  if vind>0 then deuxd.deletespectre(vind);
  choixspectre.items.delete(choixSpectre.itemindex);
  i:=NmaxSpectres2D;while deuxd.spect[i]=nil do dec(i);
  choixspectre.text:=deuxd.spect[i].nom;
  choixspectreChange(Sender);
end;

procedure TGraph4DForm.Addition1Click(Sender: TObject);
begin
  dialogScaladdform.windowState:=wsnormal;
  dialogscaladdform.operation.text:='+';
end;

procedure TGraph4DForm.Soustraction2Click(Sender: TObject);
begin
  dialogScaladdform.windowState:=wsnormal;
  dialogscaladdform.operation.text:='-';
end;

procedure TGraph4DForm.Multiplication1Click(Sender: TObject);
begin
  dialogScaladdform.windowState:=wsnormal;
  dialogscaladdform.operation.text:='*';
end;

procedure TGraph4DForm.Division1Click(Sender: TObject);
begin
  dialogScaladdform.windowState:=wsnormal;
  dialogscaladdform.operation.text:='/';
end;

procedure TGraph4DForm.Addition2Click(Sender: TObject);
begin
  dialogaddform.windowState:=wsnormal;
  dialogaddform.operation.text:='+';
end;

procedure TGraph4DForm.Soustraction3Click(Sender: TObject);
begin
  dialogaddform.windowState:=wsnormal;
  dialogaddform.operation.text:='-';
end;

procedure TGraph4DForm.Multiplication2Click(Sender: TObject);
begin
  dialogaddform.windowState:=wsnormal;
  dialogaddform.operation.text:='*';
end;

procedure TGraph4DForm.Division2Click(Sender: TObject);
begin
  dialogaddform.windowState:=wsnormal;
  dialogaddform.operation.text:='/';
end;

procedure TGraph4DForm.Rotation1Click(Sender: TObject);
var i,j:integer;
    tailleX1,tailleY1,tailleX2,tailleY2,idx1,idx2:integer;
    xmin1,xmax1,ymin1,ymax1,xstep1,ystep1,xaux,yaux,zaux,xaux2,yaux2:double;
    x1,y1,x2,y2,xmin2,xmax2,ymin2,ymax2,xc2,yc2:double;
    xc,yc,xmin_e,xmax_e,ymin_e,ymax_e:double;
    theta:double;
    xaux2_low,yaux2_low,xx,yy:integer;
begin
   theta:=RotationAngleBox.value*pi/180;
   { soit a determiner la taille du spectre de sortie }
   idx1:=deuxd.indexof(choixSpectre.text);
   tailleX1:=deuxd.spect[idx1].X;tailleY1:=deuxd.spect[idx1].Y;
   Xmin1:=min(deuxd.spect[idx1].data[0,0,0].X,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].X);
   Xmax1:=max(deuxd.spect[idx1].data[0,0,0].X,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].X);
   Ymin1:=min(deuxd.spect[idx1].data[0,0,0].Y,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].Y);
   Ymax1:=max(deuxd.spect[idx1].data[0,0,0].Y,deuxd.spect[idx1].data[tailleX1-1,tailleY1-1,0].Y);
   Xstep1:=(Xmax1-Xmin1)/(tailleX1-1);Ystep1:=(Ymax1-Ymin1)/(tailleY1-1);
   Xc:=(Xmax1+Xmin1)/2;Yc:=(Ymax1+Ymin1)/2;
   { creation du nouveau spectre }
   Xmin2:=+1e20;Xmax2:=-1e20;
   Ymin2:=+1e20;Ymax2:=-1e20;
   { determination des bords extremes du nouveau spectre }
   Xaux:=(Xmin1-Xc)*cos(theta)-(Ymin1-Yc)*sin(theta)+Xc;Yaux:=(Xmin1-Xc)*sin(theta)+(Ymin1-Yc)*cos(theta)+Yc;
   if Xaux<Xmin2 then Xmin2:=Xaux;if Xaux>Xmax2 then Xmax2:=Xaux;
   if Yaux<Ymin2 then Ymin2:=Yaux;if Yaux>Ymax2 then Ymax2:=Yaux;
   Xaux:=(Xmax1-Xc)*cos(theta)-(Ymin1-Yc)*sin(theta)+Xc;Yaux:=(Xmax1-Xc)*sin(theta)+(Ymin1-Yc)*cos(theta)+Yc;
   if Xaux<Xmin2 then Xmin2:=Xaux;if Xaux>Xmax2 then Xmax2:=Xaux;
   if Yaux<Ymin2 then Ymin2:=Yaux;if Yaux>Ymax2 then Ymax2:=Yaux;
   Xaux:=(Xmax1-Xc)*cos(theta)-(Ymax1-Yc)*sin(theta)+Xc;Yaux:=(Xmax1-Xc)*sin(theta)+(Ymax1-Yc)*cos(theta)+Yc;
   if Xaux<Xmin2 then Xmin2:=Xaux;if Xaux>Xmax2 then Xmax2:=Xaux;
   if Yaux<Ymin2 then Ymin2:=Yaux;if Yaux>Ymax2 then Ymax2:=Yaux;
   Xaux:=(Xmin1-Xc)*cos(theta)-(Ymax1-Yc)*sin(theta)+Xc;Yaux:=(Xmin1-Xc)*sin(theta)+(Ymax1-Yc)*cos(theta)+Yc;
   if Xaux<Xmin2 then Xmin2:=Xaux;if Xaux>Xmax2 then Xmax2:=Xaux;
   if Yaux<Ymin2 then Ymin2:=Yaux;if Yaux>Ymax2 then Ymax2:=Yaux;
   { creation du nouveau spectre }
   xmin2:=round(xmin2);xmax2:=round(xmax2); { attention coordonnée entières !!! }
   ymin2:=round(ymin2);ymax2:=round(ymax2);
   Xc2:=round((Xmax2+Xmin2)/2);Yc2:=round((Ymax2+Ymin2)/2);
   tailleX2:=round((xmax2-xmin2)/XStep1+1);tailleY2:=round((ymax2-ymin2)/YStep1+1);
   idx2:=deuxd.addSpectre(choixSpectre.text+'_r',TailleX2,TailleY2,1);
   deuxd.spect[idx2].typeX:=deuxd.spect[idx1].typeX;deuxd.spect[idx2].typeY:=deuxd.spect[idx1].typeY;
   { remplissage du nouveau spectre rotated X,Y, Z=0}
   for i:=0 to TailleX2-1 do
      for j:=0 to TailleY2-1 do
         begin
            x2:=xmin2+i*Xstep1;y2:=ymin2+j*Ystep1;
            deuxd.spect[idx2].data[i,j,0].X:=x2;
            deuxd.spect[idx2].data[i,j,0].Y:=y2;
            { remplissage de l'élévation }
            { détermination de l'image inverse du point (xx,yy) }
            x1:=(x2-xc2)*cos(theta)+(y2-yc2)*sin(theta)+Xc2;
            y1:=-(x2-xc2)*sin(theta)+(y2-yc2)*cos(theta)+Yc2;
            if (x1>=xmin1) and (x1<=xmax1) and (y1>=ymin1) and (y1<=ymax1)
            then deuxd.spect[idx2].data[i,j,0].Z:=deuxd.spect[idx1].interpolate2D(x1,y1)
            else deuxd.spect[idx2].data[i,j,0].Z:=0;
         end;
end;

procedure TGraph4DForm.CalculateCircularSumButtonClick(Sender: TObject);
var ind,ind1D:integer;
begin
   ind:=deuxd.indexof(ChoixSpectre.text);
   ind1D:=und.addspectre('SC',1,1,1);
   und.spect[ind1D]:=deuxd.spect[ind].SommeCirculaireSpectre2D('SC',Xcen.value,Ycen.value,BinningStepBox.value);
   sendmessage(principalform.handle,wm_redessine,0,0);
end;

procedure TGraph4DForm.MaskButtonClick(Sender: TObject);
          procedure addMask(spect:spectre);
          {effectue la sauvegarde de l'etape precedente dans NomMaskEdit_Z (si le masque existe ),
           calcul le nouveau masque et le charge dans deuxd,
           efectue la multiplication avec l'etape precedente si elle existe}
          var indM:integer;
          begin
          indM:=deuxd.indexof(NomMaskEdit.text);
          if deuxd.indexof(NomMaskEdit.text+'_Z') <>-1 then
             deuxd.delete(NomMaskEdit.text+'_Z');
          if indM <>-1 then
             deuxd.spect[indM].nom:=deuxd.spect[indM].nom+'_Z';
          deuxd.add(spect);
          if deuxd.indexof(NomMaskEdit.text+'_Z') <>-1 then
             deuxd.Multiplication(NomMaskEdit.text+'_Z',NomMaskEdit.text,NomMaskEdit.text);
          end;

begin
 if  CheckBoxMasks.checked
 then begin
     { definition à partir des positons du curseur }
     if (TypeMaskCombo.text='rectangle')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueRectExt(Xpos1.value,Ypos1.value,Xpos2.value,Ypos2.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='rectangle (slit)')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueRectInt(Xpos1.value,Ypos1.value,Xpos2.value,Ypos2.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='circle')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircExt(Xpos1.value,Ypos1.value,Xpos2.value,Ypos2.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='circle (hole)')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircInt(Xpos1.value,Ypos1.value,Xpos2.value,Ypos2.value,NomMaskEdit.text));
 end
 else begin
     { definition à partir des boites numériques }
     if (TypeMaskCombo.text='rectangle')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueRectExt(ParamBox1.value,ParamBox2.value,ParamBox3.value,ParamBox4.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='rectangle (slit)')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueRectInt(ParamBox1.value,ParamBox2.value,ParamBox3.value,ParamBox4.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='circle')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircExt(ParamBox1.value,ParamBox2.value,ParamBox1.value+ParamBox3.value,ParamBox2.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='circle (hole)')
     then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircInt(ParamBox1.value,ParamBox2.value,ParamBox1.value+ParamBox3.value,ParamBox2.value,NomMaskEdit.text));
     if (TypeMaskCombo.text='ring')
     then begin
          addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircInt(ParamBox1.value,ParamBox2.value,ParamBox1.value+ParamBox3.value,ParamBox2.value,NomMaskEdit.text));
          addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueCircExt(ParamBox1.value,ParamBox2.value,ParamBox1.value+ParamBox4.value,ParamBox2.value,NomMaskEdit.text));
          deuxd.delete(NomMaskEdit.text+'_Z');
          end;
     if (TypeMaskCombo.text='sector')
     then begin
          if symmetryBox.itemindex=0
          then addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value,ParamBox4.value,NomMaskEdit.text));
          if symmetryBox.itemindex=1
          then begin
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value,ParamBox4.value,NomMaskEdit.text+'a'));
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value+180,ParamBox4.value,NomMaskEdit.text+'b'));
               deuxd.addition(NomMaskEdit.text+'a',NomMaskEdit.text+'b',NomMaskEdit.text);
               deuxd.delete(NomMaskEdit.text+'a');deuxd.delete(NomMaskEdit.text+'b');
               end;
          if symmetryBox.itemindex=2
          then begin
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value,ParamBox4.value,NomMaskEdit.text+'a'));
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value+90,ParamBox4.value,NomMaskEdit.text+'b'));
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value+180,ParamBox4.value,NomMaskEdit.text+'c'));
               addMask(deuxd.spect[deuxd.indexof(choixSpectre.text)].MasqueSecteur(ParamBox1.value,ParamBox2.value,ParamBox3.value+270,ParamBox4.value,NomMaskEdit.text+'d')); end;
               deuxd.addition(NomMaskEdit.text+'a',NomMaskEdit.text+'b',NomMaskEdit.text+'e');
               deuxd.addition(NomMaskEdit.text+'c',NomMaskEdit.text+'d',NomMaskEdit.text+'f');
               deuxd.addition(NomMaskEdit.text+'e',NomMaskEdit.text+'f',NomMaskEdit.text);
               deuxd.delete(NomMaskEdit.text+'a');deuxd.delete(NomMaskEdit.text+'b');deuxd.delete(NomMaskEdit.text+'c');deuxd.delete(NomMaskEdit.text+'d');deuxd.delete(NomMaskEdit.text+'e');deuxd.delete(NomMaskEdit.text+'f');
          end;
     if (TypeMaskCombo.text='ringed-sector')
     then ;
     end;

end;

procedure TGraph4DForm.ReadNeXuSLLB1Click(Sender: TObject);
var vind,l:integer;
    nom,ext:string;
begin
  opendialog1.initialDir:=boitnoir.RepertoireManip.text;
  if opendialog1.execute
  then begin {le spectre est un spectre 2D}
     {extraction de l'extension}
     Nom:=ProcessFileName(opendialog1.filename);
      vind:=deuxd.indexof(nom);
      if vind=-1 then vind:=deuxd.addspectre(nom,1,1,1); {creation avec taille arbitraire, le spectre prendra ensuite la taille du fichier}
      deuxd.spect[vind].ReadFromNexusLLB(opendialog1.filename);
      MiseAjourChoixSpectre(deuxd);
      choixspectre.Text:=nom;
      LoadSpectrum(ChoixSpectre.Text);
      end;
end;

procedure TGraph4DForm.Copygraph1Click(Sender: TObject);
begin
 xyCopyStart
end;

procedure TGraph4DForm.ReaddatPAXE1Click(Sender: TObject);
var titre,date,heure,temps,ext,nomspectre,nom:string;
    vind,l:integer;
begin
opendialog1.initialDir:=boitnoir.RepertoireManip.text;
opendialog1.defaultExt:='*.dat';
opendialog1.filter:='*.dat|*.dat';
if opendialog1.execute then
   begin
   {extraction de l'extension}
   nomSpectre:=ProcessFileName(opendialog1.filename);
   vind:=deuxd.indexof(nomspectre);
   if vind=-1 then vind:=deuxd.addspectre(nomspectre,64,64,1);
   deuxd.spect[vind].readfromPAXE(opendialog1.filename,titre,nom,date,heure,temps);
   MiseAjourChoixSpectre(deuxd);
   choixspectre.Text:=nomspectre;
   LoadSpectrum(ChoixSpectre.Text);
   end;
end;

procedure TGraph4DForm.ReadTPAimage2Click(Sender: TObject);
var l:integer;
    nom,ext:string;
begin
  opendialog1.defaultExt:='*.image';
  opendialog1.filter:='*.image|*.image';
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
     {extraction de l'extension}
     nom:=ProcessFileName(opendialog1.filename);
     LectureTPAFile(OpenDialog1.FileName,nom);
     MiseAjourChoixSpectre(deuxd);
     choixspectre.Text:=nom;
     LoadSpectrum(ChoixSpectre.Text);
  end;

end;

procedure TGraph4DForm.ReadTPAimage1Click(Sender: TObject);
begin
   LectureTPAoptionsForm.windowState:=wsnormal;
end;

procedure TGraph4DForm.Read3columnsfilesXYZ1Click(Sender: TObject);
var F: TextFile;
    nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
    nom:=ProcessFileName(opendialog1.filename);
    Read3columnsfileXYZ(OpenDialog1.FileName,nom);
    MiseAjourChoixSpectre(deuxd);
    choixspectre.Text:=nom;
    LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.ReadfreeXYZ1Click(Sender: TObject);
var F: TextFile;
    nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
    nom:=ProcessFileName(Opendialog1.filename);
    ReadfreeXYZ(Opendialog1.filename,nom);
    MiseAjourChoixSpectre(deuxd);
    choixspectre.Text:=nom;
    LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.ReadfromMatlabASCII1Click(Sender: TObject);
var F: TextFile;
    nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
    nom:=ProcessFileName(opendialog1.filename);
    ReadFromMatlab(opendialog1.filename,nom);
    MiseAjourChoixSpectre(deuxd);
    choixspectre.Text:=nom;
    LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.ReadHADASPSDimage1Click(Sender: TObject);
var nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
       nom:=OpenDialog1.FileName;
       LectureFichierHADAS(nom);{ Fichier sélectionné dans la boîte de dialogue }
{       nom:=copy(nom,9,length(nom));
       choixspectre.items.add(nom);
       choixspectre.text:=nom;
       choixspectreChange(Sender); }
  end;
  MiseAJourChoixSpectre(deuxd);
end;

procedure TGraph4DForm.ReadHADASglattaftersmoothing1Click(
  Sender: TObject);
var F: textfile;
    nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
    nom:=ProcessFileName(Opendialog1.filename);
    ReadHADASglatt(OpenDialog1.FileName,nom);
    MiseAjourChoixSpectre(deuxd);
    choixspectre.Text:=nom;
    LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.ReadSDMScalculation1Click(Sender: TObject);
var
  F: TextFile;
  nom:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
    nom:=ProcessFileName(opendialog1.filename);
    Read3columnsXYZ_SDMSfile(OpenDialog1.FileName,nom);
    MiseAjourChoixSpectre(deuxd);
    choixspectre.Text:=nom;
    LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.ReadLAMPD171Click(Sender: TObject);
var l:integer;
    nom,ext:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
   {extraction de l'extension}
   nom:=ProcessFileName(opendialog1.filename);
   LectureLAMPD17File(OpenDialog1.FileName,nom);
   MiseAjourChoixSpectre(deuxd);
   choixspectre.Text:=nom;
   LoadSpectrum(ChoixSpectre.Text);
  end;
end;

procedure TGraph4DForm.SavetoASCII1Click(Sender: TObject);
var vind:integer;
begin
   vind:=deuxd.indexof(choixSpectre.text);
   savedialog1.initialDir:=boitnoir.RepertoireManip.text;
   savedialog1.defaultExt:='*.txt';
   savedialog1.filter:='*.txt|*.txt';
   deuxd.spect[vind].comment:=choixSpectre.text;
   if savedialog1.execute then
     deuxd.spect[vind].saveToASCII_3col(savedialog1.filename);
end;

procedure TGraph4DForm.Savetobinarysigend32bits1Click(Sender: TObject);
var f:file of LongInt;
    i,j:integer;
    xmax,ymax:integer;
    vind:integer;
    aux:longInt;
begin
 if savedialog1.execute then
 begin
   AssignFile(F, savedialog1.filename);{ Fichier sélectionné dans la boîte de dialogue }
   Rewrite(F);
   vind:=deuxd.indexof(choixSpectre.text);
   xmax:=deuxd.spect[vind].X;ymax:=deuxd.spect[vind].Y;
   { determination de lal taille de la matrice binaire }
   for i:=0 to xmax-1 do
      for j:=0 to ymax-1 do
      begin
         aux:=round(deuxd.spect[vind].data[i,j,0].Z);
         write(f,aux);
      end;
   CloseFile(F);
 end
end;

procedure TGraph4DForm.Savetobitmap1Click(Sender: TObject);
var bitmap:Tbitmap;
begin
 savedialog1.DefaultExt:='bmp';
 if savedialog1.execute then
 begin
{   PaintBoxContour.SaveToFile(savedialog1.filename);{ Fichier sélectionné dans la boîte de dialogue }
 end
end;

procedure TGraph4DForm.WorkingDirectoryMenuClick(Sender: TObject);
begin
   if OpenDialog1.execute
   then WorkingDirectory:=OpenDialog1.initialDir;
end;

procedure TGraph4DForm.AutoScaleCheckBoxClick(Sender: TObject);
begin
   if AutoScaleCheckBox.checked=true then begin ZminBox.Enabled:=false;ZmaxBox.Enabled:=false; end;
   if AutoScaleCheckBox.checked=false then begin ZminBox.Enabled:=true;ZmaxBox.Enabled:=true; end;
end;

procedure TGraph4DForm.FormPaint(Sender: TObject);
begin
  { on resette les curseurs }
  x1pos:=999;y1pos:=999;
  x2pos:=999;y2pos:=999;

end;

{------------------------------------------------------------------------------}
{ FONCTIONS 4D                                                                  }

procedure TGraph4DForm.PaintBox4DPaint(Sender: TObject);
const zp : Tpoint3d = (x:0;y:0;z:0);
var TailleX,TailleY,TailleZ,hoek1,hoek2,wi,he:integer;
    ok : boolean;
    xmin,xmax,ymin,ymax,zmin,zmax : double;
    d,Sz:double;
begin
  if PerspectiveCheckbox.checked then d := 5 else d := 0;
  hoek1 := scrollbar4DH.position;hoek2 := scrollbar4DV.position;
  wi := paintbox4D.width; he := paintbox4D.height;
{  if (cmode>0) then xy3dsetcolors(colorscheme[cmode]); }

  xycleargraph(paintbox4D,$f0ffff,clblack,8/8);
{  xycleargraph(paintboxSurface,clWhite,clWhite,1.0); }
  xy4dloadvolume(data4D,ok,0);

  xystartgraph(0,95,0,95,20,20,20,20,clipon);
  TailleX:=length(data4D);TailleY:=length(data4D[0]);TailleZ:=length(data4D[0,0]);
  xmin:=data4D[1,0,0];xmax:=data4D[tailleX-1,0,0];
  ymin:=data4D[0,1,0];ymax:=data4D[0,tailleY-1,0];
  zmin:=data4D[0,0,1];zmax:=data4D[0,0,tailleZ-1];
  if AutoScaleCheckBox.checked=true
  then begin zminbox.value:=dataZmin;zmaxbox.value:=dataZmax end;
  xy4dsetscale(dataZmin,dataZmax,colorscheme[cmode],8,true,ZlogCheckBox.checked);
  Sz:=(xmax-xmin)/(dataZmax-dataZmin)*ScaleSz.Position/10;
  xy3dsetframe(xmin,xmax,ymin,ymax,zmin,zmax,1,1,ScaleBar.position / 100,0);

  xy3dsetview(hoek1,hoek2,d,0);
  xy3dshowframe(4,clmaroon,-1,-1,-1,0);
  if flipBox.checked
  then
  if Iso4DBox.checked=false
  then xy4dshowvolume(point3d(xminProj.value,yminProj.value,ltminProj.value),point3d(xmaxProj.value,ymaxProj.value,ltmaxProj.value),
                point3d(xcutproj.value,ycutproj.value,ltcutproj.value),
                cutStyleBox.itemIndex,
                0,clwhite,clsilver,clgray,5,3,4) { style 3 vexels simples non interpolés }
  else xy4disovolume(isoValueBox.value,point3d(xminProj.value,yminProj.value,ltminProj.value),point3d(xmaxProj.value,ymaxProj.value,ltmaxProj.value),
                clgray,-1,2,true,false,2+64)
  else
  if Iso4DBox.checked=false
  then xy4dshowvolume(point3d(xmaxProj.value,ymaxProj.value,ltmaxProj.value),
                point3d(xminProj.value,yminProj.value,ltminProj.value),
                point3d(xcutproj.value,ycutproj.value,ltcutproj.value),
                cutStyleBox.itemIndex,
                0,clwhite,clsilver,clgray,5,3,4) { style 3 vexels simples non interpolés }
  else xy4disovolume(isoValueBox.value,point3d(xmaxProj.value,ymaxProj.value,ltmaxProj.value),point3d(xminProj.value,yminProj.value,ltminProj.value),
                clgray,-1,2,true,false,2+64);

  xy4dheightscale(wi-50,30,wi-42,he-20,'Intensity',0);
end;

procedure TGraph4DForm.ScrollBar4DVChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.ScrollBar4DHChange(Sender: TObject);
begin paintbox4D.refresh; end;

{ calcul de la coupe et stockage dans le spectre courant (validé dans la combo box) }
{ pour les coupes sans intégration on peut grandement accélerer le processus        }
{ inventer un truc pour les coupes sans intégration                                 }
{ INPUT : implicite : le spectre 3D et les bornes de l'intégration                  }
{ OUTPUT : le résultat de la projection est stocké dans le graph en cours           }
{          sélectionné dans la combBox                                              }
procedure TGraph4DForm.IntegrateButtonClick(Sender: TObject);
var  i,j,k:integer;
     indexSpectre:integer; { index du spectre courant }
     idxSpect3D:integer;  { spectre 3D sélectionnée dans la combo }
     min,max:real;
     spect2Dname:string;
     X,Y,LT:integer;
     xMinP,xMaxP,yMinP,yMaxP,ltMinP,ltMaxP:double; { variables locales pour les intervalles de projection }
begin
  xMinP:=xMinProj.value;xMaxP:=xMaxProj.value;
  yMinP:=yMinProj.value;yMaxP:=yMaxProj.value;
  ltMinP:=ltMinProj.value;ltMaxP:=ltMaxProj.value;
  idxSpect3D:=troisd.indexof(choixspectre3D.text);
if idxSpect3D>0 then
  begin
  X:=troisd.spect[idxSpect3D].X;
  Y:=troisd.spect[idxSpect3D].Y;
  LT:=troisd.spect[idxSpect3D].LT;
  end;
{ on va stocker la projection dans le spectre sélectionné dans la combo }
  spect2Dname:=choixspectre.text;
  indexSpectre:=deuxd.indexof(spect2Dname);
{ ACHTUNG :on ne peut redimensionner un spectre  sans réallouer la meoire !!!! **** }
if (indexSpectre>0) and (idxSpect3D>0) then
begin
{ ***** projection correspondant aux radiobuttons ***** }
{ c'est pas écrit de manière très élégante              }
{ projection suivant une gamme en lambda  X en abscisse Y en ordonnée }
If (XProjection.itemIndex=0) and (YProjection.itemIndex=1)
then begin
     deuxd.addspectre(spect2Dname,X,Y,1);
     for i:=0 to X-1 do
     for j:=0 to Y-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[i,j,0].x;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[i,j,0].y;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to LT-1 do
           if (troisd.spect[idxSpect3D].data[i,j,k].lt>=ltMinP) and (troisd.spect[idxSpect3D].data[i,j,k].lt<=ltMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[i,j,k].z;
       end;
     end;
{ projection suivant une gamme en Y,  X en abscisse LT en ordonnée }
If (XProjection.itemIndex=0) and (YProjection.itemIndex=2)
then begin
     deuxd.addspectre(spect2Dname,X,LT,1);
     for i:=0 to X-1 do
     for j:=0 to LT-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[i,0,j].x;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[i,0,j].lt;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to Y-1 do
           if (troisd.spect[idxSpect3D].data[i,k,j].y>=yMinP) and (troisd.spect[idxSpect3D].data[i,k,j].y<=yMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[i,k,j].z;
       end;
     end;
{ projection suivant une gamme en lambda  Y en abscisse X en ordonnée }
If (XProjection.itemIndex=1) and (YProjection.itemIndex=0)
then begin
     deuxd.addspectre(spect2Dname,Y,X,1);
     for i:=0 to Y-1 do
     for j:=0 to X-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[j,i,0].y;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[j,i,0].x;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to LT-1 do
           if (troisd.spect[idxSpect3D].data[j,i,k].lt>=ltMinP) and (troisd.spect[idxSpect3D].data[j,i,k].lt<=ltMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[j,i,k].z;
       end;
     end;
{ projection suivant X avec Y en abscisse et lambda en ordonnée }
If (XProjection.itemIndex=1) and (YProjection.itemIndex=2)
then begin
     deuxd.addspectre(spect2Dname,Y,LT,1);
     for i:=0 to Y-1 do
     for j:=0 to LT-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[0,i,j].y;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[0,i,j].lt;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to X-1 do
           if (troisd.spect[idxSpect3D].data[k,i,j].x>=xMinP) and (troisd.spect[idxSpect3D].data[k,i,j].x<=xMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[k,i,j].z;
       end;
     end;
{ projection suivant Y avec lambda  en abscisse X en ordonnée }
If (XProjection.itemIndex=2) and (YProjection.itemIndex=0)
then begin
     deuxd.addspectre(spect2Dname,LT,X,1);
     for i:=0 to LT-1 do
     for j:=0 to X-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[j,0,i].lt;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[j,0,i].x;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to Y-1 do
           if (troisd.spect[idxSpect3D].data[j,k,i].y>=yMinP) and (troisd.spect[idxSpect3D].data[j,k,i].y<=yMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[j,k,i].z;
       end;
     end;
{ projection suivant X avec lambda  en abscisse Y en ordonnée }
If (XProjection.itemIndex=2) and (YProjection.itemIndex=1)
then begin
     deuxd.addspectre(spect2Dname,LT,Y,1);
     for i:=0 to LT-1 do
     for j:=0 to Y-1 do
       begin
       deuxd.spect[indexSpectre].data[i,j,0].x:=troisd.spect[idxSpect3D].data[0,j,i].lt;
       deuxd.spect[indexSpectre].data[i,j,0].y:=troisd.spect[idxSpect3D].data[0,j,i].y;
       deuxd.spect[indexSpectre].data[i,j,0].z:=0;
       for k:=0 to X-1 do
           if (troisd.spect[idxSpect3D].data[k,j,i].x>=xMinP) and (troisd.spect[idxSpect3D].data[k,j,i].x<=xMaxP)
           then deuxd.spect[indexSpectre].data[i,j,0].z:=deuxd.spect[indexSpectre].data[i,j,0].z+troisd.spect[idxSpect3D].data[k,j,i].z;
       end;
     end;

{ réaffichage du spectre de la projection }
{  indexSpectre:=deuxd.indexof(choixspectre.text); }
    choixSpectre.text:=spect2Dname;
    deuxd.spect[indexSpectre].moniteur:=troisd.spect[idxSpect3D].moniteur; {initialisation du moniteur à la valeur globale du spectre 3D}
    X1pos:=999;Y1pos:=999;X2pos:=999;Y2pos:=999;
    LoadSpectrum(ChoixSpectre.Text);
end;

end;


procedure TGraph4DForm.CutStyleBoxChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.FlipBoxClick(Sender: TObject);
begin  paintbox4D.refresh; end;

procedure TGraph4DForm.ChoixSpectre3DChange(Sender: TObject);
begin LoadSpectrum3D(ChoixSpectre3D.Text); end;

procedure TGraph4DForm.XminProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.YminProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.ltMinProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.XmaxProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.YmaxProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.ltMaxProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.XcutProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.YcutProjChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.LTcutprojChange(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.SpinXClick(Sender: TObject; Button: TUDBtnType);
var ind,TailleX:integer;
    xmin,xstep:double;
begin
  TailleX:=length(data4D);
  xmin:=data4D[1,0,0];xstep:=data4D[2,0,0]-data4D[1,0,0];
  XcutProj.value:=xmin+spinX.position*xstep;
  paintbox4D.refresh;
end;

procedure TGraph4DForm.SpinYClick(Sender: TObject; Button: TUDBtnType);
var ind,TailleY:integer;
    ymin,ystep:double;
begin
  TailleY:=length(data4D[0]);
  ymin:=data4D[0,1,0];ystep:=data4D[0,2,0]-data4D[0,1,0];
  YcutProj.value:=ymin+spinY.position*ystep;
  paintbox4D.refresh;
end;

procedure TGraph4DForm.SpinLTClick(Sender: TObject; Button: TUDBtnType);
var ind,TailleLT:integer;
    ltmin,ltstep:double;
begin
  TailleLT:=length(data4D[0,0]);
  ltmin:=data4D[0,0,1];ltstep:=data4D[0,0,2]-data4D[0,0,1];
  LTcutProj.value:=ltmin+spinLT.position*ltstep;
  paintbox4D.refresh;
end;

procedure TGraph4DForm.Reset3D;
var ind,TailleX,TailleY,TailleLT:integer;
    xmin,xmax,ymin,ymax,ltmin,ltmax,xstep,ystep,ltstep:double;
begin
  TailleX:=length(data4D);TailleY:=length(data4D[0]);TailleLT:=length(data4D[0,0]);
  xmin:=data4D[1,0,0];xmax:=data4D[tailleX-1,0,0];xstep:=data4D[2,0,0]-data4D[1,0,0];
  ymin:=data4D[0,1,0];ymax:=data4D[0,tailleY-1,0];ystep:=data4D[0,2,0]-data4D[0,1,0];
  ltmin:=data4D[0,0,1];ltmax:=data4D[0,0,tailleLT-1];ltstep:=data4D[0,0,2]-data4D[0,0,1];
  XminProj.value:=xmin;YminProj.value:=ymin;LTminProj.value:=ltmin;
  XmaxProj.value:=xmax;YmaxProj.value:=ymax;LTmaxProj.value:=ltmax;
  XcutProj.value:=(xmax+xmin)/2;YcutProj.value:=(ymax+ymin)/2;LTcutProj.value:=(ltmax+ltmin)/2;
  spinX.Min:=0;spinX.Max:=TailleX;spinX.Increment:=1;
  spinY.Min:=0;spinY.Max:=TailleY;spinY.Increment:=1;
  spinLT.Min:=0;spinLT.Max:=TailleLT;spinLT.Increment:=1;

  ScrollBar4DH.Position:=45;{ScrollBar4DH.update; }
  ScrollBar4DV.Position:=20;{ScrollBar4DV.update; }
end;

{ remise à zéro des différentes boites }
procedure TGraph4DForm.Button2Click(Sender: TObject);
begin Reset3D end;

{ extraction de la zone sélectionnnée sur le graph par les deux curseurs }
procedure TGraph4DForm.Extract3DbuttonClick(Sender: TObject);
var i,j,k:integer;
    tailleX1,tailleY1,tailleLT1,tailleX2,tailleY2,tailleLT2,idx1,idx2:integer;
    xmin1,xmax1,ymin1,ymax1,ltmin1,ltmax1,xstep1,ystep1,ltstep1,xaux,yaux,ltaux,zaux:double;
    xmin_e,xmax_e,ymin_e,ymax_e,ltmin_e,ltmax_e,x1,x2,y1,y2,lt1,lt2:double;
begin
    { soit a determiner la taille du spectre de sortie }
    idx1:=troisd.indexof(choixSpectre3D.text);
    tailleX1:=troisd.spect[idx1].X;tailleY1:=troisd.spect[idx1].Y;tailleLT1:=troisd.spect[idx1].LT;
    Xmin1:=min(troisd.spect[idx1].data[0,0,0].X,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].X);
    Xmax1:=max(troisd.spect[idx1].data[0,0,0].X,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].X);
    Ymin1:=min(troisd.spect[idx1].data[0,0,0].Y,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].Y);
    Ymax1:=max(troisd.spect[idx1].data[0,0,0].Y,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].Y);
    LTmin1:=min(troisd.spect[idx1].data[0,0,0].LT,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].LT);
    LTmax1:=max(troisd.spect[idx1].data[0,0,0].LT,troisd.spect[idx1].data[tailleX1-1,tailleY1-1,tailleLT1-1].LT);
    Xstep1:=(Xmax1-Xmin1)/(tailleX1-1);Ystep1:=(Ymax1-Ymin1)/(tailleY1-1);LTstep1:=(LTmax1-LTmin1)/(tailleLT1-1);
    { creation du nouveau spectre } { on détermine les poinsts extremes }
    X1:=troisd.spect[idx1].data[trunc((XminProj.value-Xmin1)/Xstep1),0,0].X;
    Y1:=troisd.spect[idx1].data[0,trunc((YminProj.value-Ymin1)/Ystep1),0].Y;
    LT1:=troisd.spect[idx1].data[0,0,trunc((LTminProj.value-LTmin1)/LTstep1)].LT;
    X2:=troisd.spect[idx1].data[trunc((XmaxProj.value-Xmin1)/Xstep1)+1,0,0].X;
    Y2:=troisd.spect[idx1].data[0,trunc((YmaxProj.value-Ymin1)/Ystep1)+1,0].Y;
    LT2:=troisd.spect[idx1].data[0,0,trunc((LTmaxProj.value-LTmin1)/LTstep1)+1].LT;

    xmin_e:=min(X1,X2);xmax_e:=max(X1,X2);
    ymin_e:=min(Y1,Y2);ymax_e:=max(Y1,Y2);
    ltmin_e:=min(LT1,LT2);ltmax_e:=max(LT1,LT2);
    tailleX2:=round((xmax_e-xmin_e)/XStep1+1);
    tailleY2:=round((ymax_e-ymin_e)/YStep1+1);
    tailleLT2:=round((ltmax_e-ltmin_e)/LTStep1+1);
    { determination de la taille du nouveau spectre et initialisation }
    idx2:=troisd.addSpectre(choixSpectre3D.text+'_e',TailleX2,TailleY2,TailleLT2);
    troisd.spect[idx2].typeX:=troisd.spect[idx1].typeX;troisd.spect[idx2].typeY:=troisd.spect[idx1].typeY;troisd.spect[idx2].typeLT:=troisd.spect[idx1].typeLT;
    { remplissage du nouveau spectre }
    { scan du premier spectre }
    for i:=0 to TailleX1-1 do
      for j:=0 to TailleY1-1 do
        for k:=0 to TailleLT1-1 do
          begin
            xaux:=troisd.spect[idx1].data[i,j,k].x;
            yaux:=troisd.spect[idx1].data[i,j,k].y;
            ltaux:=troisd.spect[idx1].data[i,j,k].lt;
            zaux:=troisd.spect[idx1].data[i,j,k].z;
            if (xaux>=xmin_e) and (xaux<=xmax_e)
            and (yaux>=ymin_e) and (yaux<=ymax_e)
            and (ltaux>=ltmin_e) and (ltaux<=ltmax_e)
            then begin
                 troisd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),round((ltaux-ltmin_e)/ltstep1)].X:=xaux;
                 troisd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),round((ltaux-ltmin_e)/ltstep1)].Y:=yaux;
                 troisd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),round((ltaux-ltmin_e)/ltstep1)].LT:=ltaux;
                 troisd.spect[idx2].data[round((xaux-xmin_e)/xstep1),round((yaux-ymin_e)/ystep1),round((ltaux-ltmin_e)/ltstep1)].Z:=zaux;
                 end;
          end;
  MiseAjourChoixSpectre3D(troisd);
end;

{ calcul de la coupe et stockage dans le spectre courant (validé dans la combo box) }
{ pour les coupes sans intégration on peut grandement accélerer le processus        }
{ inventer un truc pour les coupes sans intégration                                 }
{ INPUT : implicite : le spectre 3D et les bornes de l'intégration                  }
{ OUTPUT : le résultat de la projection est stocké dans le graph en cours           }
{          sélectionné dans la combBox                                              }
procedure TGraph4DForm.ProjectButtonClick(Sender: TObject);
var  i,j,k:integer;
     ind3,ind:integer;
     spect2Dname:string;
     X,Y,LT:integer;
     xP,yP,ltP,xmin,ymin,ltmin,xStep,yStep,ltStep:double; { variables locales pour les intervalles de projection }
begin
  xP:=xMinProj.value;
  yP:=yMinProj.value;
  ltP:=ltMinProj.value;
{  TailleX:=length(data4D);TailleY:=length(data4D[0]);TailleLT:=length(data4D[0,0]); }
  xmin:=data4D[1,0,0];xstep:=data4D[2,0,0]-data4D[1,0,0];
  ymin:=data4D[0,1,0];ystep:=data4D[0,2,0]-data4D[0,1,0];
  ltmin:=data4D[0,0,1];ltstep:=data4D[0,0,2]-data4D[0,0,1];

  ind3:=troisd.indexof(choixspectre3D.text);
  X:=troisd.spect[ind3].X;Y:=troisd.spect[ind3].Y;LT:=troisd.spect[ind3].LT;
  spect2Dname:=choixspectre3D.text+'_p';

  if (ind3>0) then
  begin
   { ***** projection correspondant aux radiobuttons ***** }
   { projection suivant une gamme en lambda  X en abscisse Y en ordonnée }
   If (XProjection.itemIndex=0) and (YProjection.itemIndex=1)
   then begin
     ind:=deuxd.addspectre(spect2Dname,X,Y,1);
     for i:=0 to X-1 do
     for j:=0 to Y-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[i,j,0].x;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[i,j,0].y;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[i,j,round((ltp-ltmin)/ltstep)].z;
       end;
     end;
   { projection suivant une gamme en Y,  X en abscisse LT en ordonnée }
   If (XProjection.itemIndex=0) and (YProjection.itemIndex=2)
   then begin
     ind:=deuxd.addspectre(spect2Dname,X,LT,1);
     for i:=0 to X-1 do
     for j:=0 to LT-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[i,0,j].x;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[i,0,j].lt;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[i,round((yp-ymin)/ltstep),j].z;
       end;
     end;
   { projection suivant une gamme en lambda  Y en abscisse X en ordonnée }
   If (XProjection.itemIndex=1) and (YProjection.itemIndex=0)
   then begin
     ind:=deuxd.addspectre(spect2Dname,Y,X,1);
     for i:=0 to Y-1 do
     for j:=0 to X-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[j,i,0].y;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[j,i,0].x;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[j,i,round((ltp-ltmin)/ltstep)].z;
       end;
     end;
   { projection suivant X avec Y en abscisse et lambda en ordonnée }
   If (XProjection.itemIndex=1) and (YProjection.itemIndex=2)
   then begin
     ind:=deuxd.addspectre(spect2Dname,Y,LT,1);
     for i:=0 to Y-1 do
     for j:=0 to LT-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[0,i,j].y;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[0,i,j].lt;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[round((xp-xmin)/xstep),i,j].z;
       end;
     end;
   { projection suivant Y avec lambda  en abscisse X en ordonnée }
   If (XProjection.itemIndex=2) and (YProjection.itemIndex=0)
   then begin
     ind:=deuxd.addspectre(spect2Dname,LT,X,1);
     for i:=0 to LT-1 do
     for j:=0 to X-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[j,0,i].lt;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[j,0,i].x;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[j,round((yp-ymin)/ltstep),i].z;
       end;
     end;
   { projection suivant X avec lambda  en abscisse Y en ordonnée }
   If (XProjection.itemIndex=2) and (YProjection.itemIndex=1)
   then begin
     ind:=deuxd.addspectre(spect2Dname,LT,Y,1);
     for i:=0 to LT-1 do
     for j:=0 to Y-1 do
       begin
       deuxd.spect[ind].data[i,j,0].x:=troisd.spect[ind3].data[0,j,i].lt;
       deuxd.spect[ind].data[i,j,0].y:=troisd.spect[ind3].data[0,j,i].y;
       deuxd.spect[ind].data[i,j,0].z:=troisd.spect[ind3].data[round((xp-xmin)/xstep),j,i].z;
       end;
     end;
{ réaffichage du spectre de la projection }
    choixSpectre.text:=spect2Dname;
    deuxd.spect[ind].moniteur:=troisd.spect[ind3].moniteur; {initialisation du moniteur à la valeur globale du spectre 3D}
    LoadSpectrum(ChoixSpectre.Text);
end;
end;

procedure TGraph4DForm.Iso4DBoxClick(Sender: TObject);
begin paintbox4D.refresh; end;

procedure TGraph4DForm.IsoValueBoxKeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.XminProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.XmaxProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.XcutProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.YminProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.YmaxProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.YcutProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.ltMinProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.ltMaxProjKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;
procedure TGraph4DForm.LTcutprojKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin if key=13 then paintbox4D.refresh; end;

{ lecture des spectres OOMMF en 3D }
procedure TGraph4DForm.OvFOOMMFascii1Click(Sender: TObject);
var l:integer;
    nom,ext:string;
begin
  if OpenDialog1.Execute then  { Affichage de la boîte de dialogue d'ouverture }
  begin
   {extraction de l'extension}
   nom:=ProcessFileName(opendialog1.filename);
   ReadOVFfile3D(OpenDialog1.FileName,nom);
   MiseAjourChoixSpectre3D(troisd);
   choixspectre3D.Text:=nom+'_M';
   LoadSpectrum3D(ChoixSpectre3D.Text);
  end;
end;

end.


