unit CalDatau;

interface
uses
  SysUtils,
  ULRecTyp, ULObju, Fileu,
  UlanType, UlanGlob,
  ULPRType, ULPRObju, ULCType, ULCObju,
  UCFType, UCFObju, UCFRType, UCFRObju,
  UCPType, UCPObju, UCPRType, UCPRObju,
  DataFileu;

type
  TCalData = class(TDataFile)
  private
    FULC: TULCObj; { composed calibration branch }
    FULC_UCF: TUCFObj;
    FULC_UCP: TUCPObj;
    function GetULC: TULCObj;
    function GetULC_UCF: TUCFObj;
    function GetULC_UCP: TUCPObj;
    {v0.76.1}
    function GetActiveUCPR: TUCPRObj;
    {/v0.76.1}
  protected
    procedure ULFFree;override;
    function GetFileExt: string; override;
    {v0.67}
    function HasData: boolean; override;
    procedure DiscardData; override;
    function GetTemplateExt: string; override;
    {/v0.67}
    {v0.76.1}
    procedure SetDefDir(const ADir: string);
    function GetDefDir: string;
    {/v0.76.1}

  public
    procedure ComposePeaks;
      procedure ComposePeaksByAverage;
    {v0.76.1}
    procedure FileAdd(const AFileName: string);
    {/v0.76.1}

    property ULC: TULCObj read GetULC;
    property ULC_UCF: TUCFObj read GetULC_UCF;
    property ULC_UCP: TUCPObj read GetULC_UCP;
    {v0.76.1}
    property ActiveUCPR: TUCPRObj read GetActiveUCPR;
    property DefDir: string read GetDefDir write SetDefDir;
    {/v0.76.1}

  end;

  
implementation
uses
  Spectrum;
{TCalData.}
{v0.64}
function TCalData.GetULC: TULCObj;
begin
  if (FULC = nil) then
    FULC := TULCObj(ULF.FindOrAdd(ULCID, ''));
  Result := FULC;
end;

function TCalData.GetULC_UCF: TUCFObj;
begin
  if FULC_UCF = nil then
    FULC_UCF := TUCFObj(ULC.FindOrAdd(UCFID, ''));
  Result := FULC_UCF;
end;

function TCalData.GetULC_UCP: TUCPObj;
begin
  if FULC_UCP = nil then
    FULC_UCP := TUCPObj(ULC.FindOrAdd(UCPID, ''));
  Result := FULC_UCP;
end;
{/v0.64}

function CreateOrOpenCalFile(AFileName: string; var ACalData: TCalData): boolean;
var
  d: TCalData;
  fn: string;
begin
  ACalData := nil;
  if (AFileName = '') or (not FileExists(AFileName)) then begin
    //fn := AddBackSlash(TemplateDir) + pvUlanDefaultTemplate;
    //if not FileExists(fn) then
    //  fn := AddBackSlash(TemplateDir) + pvPasiveDefaultTemplate;
    fn := AFileName;
    d := TCalData.Create(fn, omCreate);
  end else begin
    fn := AFileName;
    d := TCalData.Create(fn, omRead);
  end;
  //d := TAcqData.Create(fn, omRead);
  try
    {
    if d.ULI.Duration <> 0 then begin
      ul := NewUserViewLimit;
      d.ULVL.MinX := ul.Min.X;
      d.ULVL.MinY := ul.Min.Y;
      d.ULVL.MaxX := d.ULI.Duration / 60; //min
      d.ULVL.MaxY := ul.Max.Y;
    end;
    }
    if AFileName <> '' then begin
      d.SaveTo(AFileName);
    end;
  except
    d.Free;
  end;
  ACalData := d;
  Result := true;
end;
{v0.65}
procedure TCalData.ComposePeaksByAverage;
// ucprtype ulanrecs.lst
  { scan all selected files for named peaks,
    create compoused peaks from them using switch:
      - intersection (only peaks present in all files)
      - union (all peaks found in any file)

    for each composed peak compute weighted average using Weight field:
      response := response[i] * weight[i] / sum of weights
      x := x[i] * weight[i] / sum of weights
  }
var
  i, j: integer;

  oucfr: TULObj;
  ucfr: TUCFRObj absolute oucfr;

  oucpr: TULObj;
  ucpr: TUCPRObj absolute oucpr;

  op: TULObj;
  p: TULPRObj absolute op;

  f: TAcqData;
  w: single;
  fcount: integer;

//
begin
  ULC_UCP.Clear;
  fcount := 0;
  for i := 0 to ULC_UCF.ChildCount - 1 do begin
    oucfr := ULC_UCF.Childs[i];
    if not (oucfr is TUCFRObj) then
      continue;

    // ulctype ucptype ucprtype ucftype ucfrtype ulprtype ulrectyp

    f := TAcqData.Create(ucfr.FileName, omRead);
    try
      inc(fcount);
      w := ucfr.Weight;
      if w = 0 then
        w := 1;
      for j := 0 to f.ULP.ChildCount - 1 do begin
        op := f.ULP.Childs[j];
        if not (op is TULPRObj) then
          continue;
        if not ULC_UCP.HasChildWithFieldUsrValue('PeakName', p.PeakName, oucpr) then begin
          oucpr := ULC_UCP.Add(UCPRID);//ulobju
          ucpr.PeakName := p.PeakName;
          ucpr.DataName := p.DataName;
        end;

        ucpr.FromFileCount := ucpr.FromFileCount + 1;
        ucpr.WeightSum := ucpr.WeightSum + w;
        ucpr.Response := ucpr.Response + p.Response * w;
        ucpr.X := ucpr.X + p.X * w;
      end;
    finally
      f.Free;
    end;
  end;

  i := 0;
  while i < ULC_UCP.ChildCount do begin
    oucpr := ULC_UCP.Childs[i];
    if not (oucpr is TUCPRObj) then
      continue;
    if ULC.PeakFindKind = pfkAND then begin
      if ucpr.FromFileCount < fcount then begin
        ucpr.Free;
        continue;
      end;
    end;
    ucpr.Response := ucpr.Response / ucpr.WeightSum;
    ucpr.X := ucpr.X / ucpr.WeightSum;
    inc(i);
  end;

end;

procedure TCalData.ComposePeaks;
begin
  ComposePeaksByAverage;//for now
end;

procedure TCalData.ULFFree;
begin
  FULC := nil;
    FULC_UCP := nil;
    FULC_UCF := nil;
  inherited;
end;

function TCalData.GetFileExt: string;
begin
  Result := ULCExt;
end;
{v0.67}
function TCalData.HasData: boolean;
begin
  Result := true;
end;

procedure TCalData.DiscardData;
begin
end;

function TCalData.GetTemplateExt: string;
begin
  Result := FileExt;
end;
{/v0.67}

{v0.76.1}
function TCalData.GetActiveUCPR: TUCPRObj;
var o: TULObj;
begin
  o := FULC_UCP.ActiveChild;
  if o.RecID = UCPRID then
    Result := TUCPRObj(o)
  else
    Result := nil;
end;

procedure TCalData.FileAdd(const AFileName: string);
var
  f: TUCFRObj;
  fn: string;
begin
  f := TUCFRObj(ULC_UCF.Add(UCFRID));
  if ExtractFilePath(AFileName) = '' then
    fn := DefDir + AFileName
  else
    fn := AFileName;
  f.FileName := ExtractRelativePath(DefDir, fn);
end;

procedure TCalData.SetDefDir(const ADir: string);
begin
  ULC_UCF.DefDir := SysUtils.IncludeTrailingPathDelimiter(ADir);
end;

function TCalData.GetDefDir: string;
begin
  Result := ULC_UCF.DefDir;
end;
{/v0.76.1}

{/TCalData.}

end.
