⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpactive.pas

📁 生物信息学中的遗传数据分析的delphi源码。
💻 PAS
字号:


{$I CPDIR.INC}


unit cpactive;

{
   Holds info on currently active leaves, outgroup, rooting, and
   ladder order.

   24 Sep 1991 Code cleaned up.
   28 Jan 1993 Bug in MakeActiveleaves fixed. Previously a simple assignment
               ALeaves = AL was used, which failed horribly.
}

interface

uses
   cpvars,
   cpset,
   cptree,
   WObjects;


type
   ACTOBJ_PTR = ^ACTIVEOBJ;
      {Pointer to [ACTIVEOBJ] }
   ACTIVEOBJ = object (TObject)
      { Activities object }
      nOLeaves : 0..MAXLEAVES;    {Original unpruned leaf count }
      ALeaves : CLUSTEROBJ; {Set of active leaves, numbered by order in input file }
      AOutgroup : CLUSTEROBJ; {Set of outgroup leaves, numbered by order in input file }
      ALadder : LADDERTYPE; {Ladder order}
      AReRoot : Boolean;{Reroot flag}
      APrune : Boolean;{Prune flag}
      nALeaves : 0..MAXLEAVES;    {Number of currently active leaves }


      constructor Load (var S: TStream);
         {Load object from stream <\b S> }
      procedure Store (var S: TStream);
         {Store object in stream <\b S> }

      function NewOutgroup (var s: CLUSTEROBJ):Boolean;
         {True if outgroup <\b s> is not the same as the current outgroup [AOutgroup] }
      procedure AdjustTree (var T:TREEOBJ);
         {Calls [FastAdjustTree] to prune and root tree <\b T>, then
          ladderizes it in [[ALadder]] order}
      procedure FastAdjustTree (var T:TREEOBJ);
         {Prune from tree <\b T> any nonactive leaves and then root
          with current outgroup (if any). Sets the tree's [fl_PRUNED] flag
          and calls the tree's [OrderLeaves] method.}
      function IthActiveLeaf (IthLeaf:integer):integer;
         {Return the <\b Ithleaf> element of [[ALeaves]]}
      function NLeavesActive:integer;
         {Return the number of active leaves}
      function IsActive (Leaf:integer):Boolean;
         {True if <\b Leaf> is in [[ALeaves]]}
      function BiggestLeaf:integer;
         {Return the highest active leaf}
      function OrigLeaves:integer;
         {Return the number of active leaves}
      procedure SetDefault (i:integer);
         {Set the defaults values of all the fields:
         [[nOLeaves]] = <\b i>
         [[nALeaves]] = <\b i>
         [[ALeaves]] = \[1..<\b i>\]
         [[AOutgroup]] = \[ \]
         [[ALadder]] = [LEFTINDEX];
         [[AReRoot]] = FALSE;
         [[APrune]]  = FALSE;
         }
      procedure SetLadder (L:LADDERTYPE);
         {Set [[ALadder]] to <\b L>}
      procedure Activeleaves (s:CLUSTER);
         {Return in <\b s> the set of active leaves}
      procedure SetOutGroup (s:CLUSTER);
         {Set the outgrpup to <\b s>}
      procedure MakeOutgroup (var OG:CLUSTEROBJ);
         { Make <\b OG> the current outgroup. The leaves in <\b OG> are
           labeled with their order in the set of currently active leaves,
           so procedure translates labels into order in input file. }
      procedure SetOptions (LV:CLUSTER; LA:LADDERTYPE;
                            RR:BOOLEAN; OG:CLUSTER);
         {Set fields to supplied values}
      procedure SetOpt (LV:CLUSTEROBJ; LA:LADDERTYPE;
                            RR:BOOLEAN; OG:CLUSTEROBJ);
         {Set fields to supplied values}         
      procedure MakeCopy (var ACopy:ACTIVEOBJ);
         {Return a copy of the object in <\b ACopy> }
      procedure Dump (var f:text);
         {Dump the object's fields to the file <\b f>}
      procedure PruneTree (var T:TREEOBJ);
         {Prune the nonactive leaves from <\b T>. Sets the tree's [fl_PRUNED] flag
          and calls the tree's [OrderLeaves] method.}
      function HavePrunedOutgroup:Boolean;
         {True if the set of active leave does not include the outgroup. }
      function Pruned (var s:CLUSTEROBJ):Boolean;
         {True if the set of active leaves is included in <\b s>}
      procedure MakeActiveLeaves (var AL: CLUSTEROBJ);
         {Makes <\b AL> the set of active leaves, sets [nALeaves] to the
         cardinality of <\b AL>, and sets the flag [APrune] if that value
         is less than [[nOLeaves]]}
      function OrderInPrunedLeaves (Leaf:integer):integer;
         {Return the relative position of <\b Leaf> in the set of active leaves}
      end;

const
  RACTIVEOBJ: TStreamRec = (
    ObjType: 106;
    VmtLink: Ofs(TypeOf(ACTIVEOBJ)^);
    Load:    @ACTIVEOBJ.Load;
    Store:   @ACTIVEOBJ.Store);
    {Registration record for ACTIVEOBJ}


implementation

   constructor ACTIVEOBJ.Load (var S: TStream);
   begin
      S.Read (nOLeaves, SizeOf(nOLeaves));
      S.Read (ALadder, SizeOf(ALadder));
      S.Read (AReRoot, SizeOf(AReRoot));
      S.Read (APrune, SizeOf(APrune));
      S.Read (nALeaves, SizeOf(nALeaves));
      ALeaves.Load (S);
      AOutgroup.Load (S);
   end;

   procedure ACTIVEOBJ.Store (var S: TStream);
   begin
      S.Write (nOLeaves, SizeOf(nOLeaves));
      S.Write (ALadder, SizeOf(ALadder));
      S.Write (AReRoot, SizeOf(AReRoot));
      S.Write (APrune, SizeOf(APrune));
      S.Write (nALeaves, SizeOf(nALeaves));
      ALeaves.Store (S);
      AOutgroup.Store (S);
   end;

   function ACTIVEOBJ.OrderInPrunedLeaves (Leaf:integer):integer;
   var
      i, j:integer;
   begin
      i := 0;
      j := 0;
      while (i <> Leaf) do begin
         Inc (i);
         if (ALeaves.IsElement (i)) then
            Inc (j);
         end;
      OrderInPrunedLeaves := j;
   end;

{-----------------------------SetDefault-----------------------------------}

   procedure ACTIVEOBJ.SetDefault(i:integer);
   begin
      nOLeaves := i;
      nALeaves := i;
      ALeaves.FullSet (nOLeaves);
      AOutgroup.NullSet;
      ALadder := LEFTINDEX;
      AReRoot := FALSE;
      APrune  := FALSE;
   end;

{-----------------------------SetLadder------------------------------------}

   procedure ACTIVEOBJ.SetLadder (L:LADDERTYPE);
   begin
      ALadder := L;
   end;

{-----------------------------ActiveLeaves---------------------------------}

   procedure ACTIVEOBJ.ActiveLeaves (s:CLUSTER);
   begin
      ALeaves.MakeSet (s);
      nALeaves := ALeaves.Cardinality;
      APrune  := (nALeaves < nOLeaves);
   end;


   procedure ACTIVEOBJ.MakeActiveLeaves (var AL: CLUSTEROBJ);
   var
      i, j: integer;
   begin
      ALeaves.NullSet;
      i := 0;
      j := 0;
      while (i < nOLeaves) do begin
         Inc (i);
         if AL.IsElement (i) then begin
            Inc (j);
            ALeaves.AddToSet (i);
            end;
         end;
      nALeaves := j;
      APrune  := (nALeaves < nOLeaves);
   end;

{-----------------------------NLeavesActive--------------------------------}

   function ACTIVEOBJ.NLeavesActive:integer;
   { no. of active leaves }
   begin
      NLeavesActive := nALeaves;
   end;

{-----------------------------OrigLeaves-----------------------------------}

   function ACTIVEOBJ.OrigLeaves:integer;
   { original no. of leaves in profile }
   begin
      OrigLeaves := nOLeaves;
   end;

{-----------------------------IsActive-------------------------------------}

   function ACTIVEOBJ.IsActive (Leaf:integer):Boolean;
   begin
      IsActive := (ALeaves.IsElement (Leaf));
   end;

{-----------------------------IthActiveLeaf--------------------------------}

   function ACTIVEOBJ.IthActiveLeaf (IthLeaf:integer):integer;
   var
      i, j: integer;
   begin
      j := 0;
      i := 0;
      while (i < IthLeaf) do begin
         Inc (j);
         if IsActive (j) then
            Inc (i);
         end;
      IthActiveLeaf := j;
   end;


{-----------------------------BiggestLeaf----------------------------------}

   function ACTIVEOBJ.BiggestLeaf:integer;
   { Largest active leaf }
   begin
      if (nOLeaves = nALeaves) then
         BiggestLeaf := nOLeaves
      else BiggestLeaf := ALeaves.LastElement;
   end;


   { Make an outgroup from OG, which contains current outgroup
     where the leaves are labeled with their order in the set of
     active leaves, so we need to convert back to original numbers.
   }
   procedure ACTIVEOBJ.MakeOutGroup (var OG:CLUSTEROBJ);
   var
       i, j: integer;
   begin
      AOutgroup.NullSet;
      i := 0;
      j := 0;
      while (j < nOLeaves) do begin
         repeat
               Inc (j);
         until ALeaves.IsElement(j);
         Inc (i);
         if OG.IsElement (i) then
            AOutgroup.AddToSet (j);
         end;
   end;

   { True if outgroup s is not the same as the current outgroup }
   function ACTIVEOBJ.NewOutgroup (var s: CLUSTEROBJ):Boolean;
   begin
      NewOutgroup := (AOutGroup.Relationship (s) <> IDENTITY);
   end;

   { True if currently active leaves are a subset of the
     set s [the set of newly choosen active leaves] }
   function ACTIVEOBJ.Pruned (var s:CLUSTEROBJ):Boolean;
   begin
      Pruned := (ALeaves.Relationship (s) = SUPERSET);
   end;

{-----------------------------SetOutgroup----------------------------------}

   procedure ACTIVEOBJ.SetOutgroup (s:CLUSTER);
   begin
      AOutGroup.MakeSet (s);
   end;

{-----------------------------SetOptions-----------------------------------}

   procedure ACTIVEOBJ.SetOptions (LV:CLUSTER; LA:LADDERTYPE; RR:BOOLEAN; OG:CLUSTER);
   { quick and dirty options setting }
   begin
      ActiveLeaves (LV);
      SetLadder (LA);
      AReRoot := RR;
      SetOutGroup (OG);
   end;

{-----------------------------SetOpt---------------------------------------}

   procedure ACTIVEOBJ.SetOpt (LV:CLUSTEROBJ; LA:LADDERTYPE;
                               RR:BOOLEAN; OG:CLUSTEROBJ);
   { quick and dirty options setting }
   begin
      ALeaves :=LV;
      nALeaves := ALeaves.Cardinality;
      APrune  := (nALeaves < nOLeaves);

      SetLadder (LA);
      AReRoot := RR;
      AOutGroup :=OG;
   end;

{-----------------------------Dump-----------------------------------------}

   procedure ACTIVEOBJ.Dump (var f:text);
   begin
      writeln (f);
      writeln (f, 'Current options');
      writeln (f, '---------------');
      writeln (f);
      if APrune  then
         writeln (f, 'Trees are pruned');
      ALeaves.ShowSet   ('     Active leaves :');
      writeln (f);
      if AReRoot then
         writeln (f, 'Reroot trees');
      AOutGroup.ShowSet ('          Outgroup :');
      writeln (f);
      write (f, '            Ladder : ');
      case ALadder of
         DEFAULT: writeln (f, 'DEFAULT');
         LEFT:    writeln (f, 'LEFT');
         RIGHT:   writeln (f, 'RIGHT');
         end;
      writeln (f);
   end;

{-----------------------------AdjustTree-----------------------------------}

   procedure ACTIVEOBJ.AdjustTree (var T:TREEOBJ);
   { Prune and root tree according to
     current settings. Checks that
     current outgroup contains at least
     one active leaf.

     Do ladderize. }
   begin
      { Prune and root }
      FastAdjustTree (T);

      { Ladderize }
      T.Ladderize (ALadder);
   end;


{-----------------------------FastAdjustTree-------------------------------}

   procedure ACTIVEOBJ.FastAdjustTree (var T:TREEOBJ);
   { Prune and root tree according to
     current settings. Checks that
     current outgroup contains at least
     one active leaf.

     To save time, doesn't reorder tree.
   }
   var
      OG_PTR: NODE_PTR;
      i: integer;
      CommonLeaves : CLUSTEROBJ;
   begin
      { Prune leaves }
      if APrune then begin
         for i := 1 to nOLeaves do
            if not ALeaves.IsElement (i) then begin
               T.PruneLeaf (i);
               end;
         T.SetFlag (fl_PRUNED, True);
         end;
      T.OrderLeaves;

      { Root using outgroup }
      if AReRoot then begin
         { Ensure that there are leaves in common to
           current set of leaves and the outgroup. }
         ALeaves.Intersection (AOutGroup, CommonLeaves);
         if not CommonLeaves.Empty then
            if T.CanReRoot (AOutGroup, OG_PTR) then
               T.ReRoot (OG_PTR);
         end;
   end;


{-----------------------------PruneTree------------------------------------}

   { Just prune leaves off tree }
   procedure ACTIVEOBJ.PruneTree (var T:TREEOBJ);
   var
      i: integer;
   begin
      { Prune leaves }
      if APrune then begin
         for i := 1 to nOLeaves do
            if not ALeaves.IsElement (i) then begin
               T.PruneLeaf (i);
               end;
         T.SetFlag (fl_PRUNED, True);
         end;
      T.OrderLeaves;
   end;

{-----------------------------MakeCopy-------------------------------------}

   procedure ACTIVEOBJ.MakeCopy (var ACopy:ACTIVEOBJ);
   begin
      ACopy.SetDefault (nOLeaves);
      ACopy.SetOpt (ALeaves,ALadder,AReRoot,AOutgroup);
   end;

{ True if pruned set of leaves "CurrentLeaves" does not
  contain the current outgroup. }
function ACTIVEOBJ.HavePrunedOutgroup:Boolean;
begin
   HavePrunedOutGroup := false;
   if not AOutgroup.Empty then
      HavePrunedOutgroup := (ALeaves.Relationship (AOutGroup) = DISJOINT);
end;

begin
   RegisterType (RActiveObj);
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -