1 //  $Id: mmdb_mask.cpp $
2 //  =================================================================
3 //
4 //   CCP4 Coordinate Library: support of coordinate-related
5 //   functionality in protein crystallography applications.
6 //
7 //   Copyright (C) Eugene Krissinel 2000-2013.
8 //
9 //    This library is free software: you can redistribute it and/or
10 //    modify it under the terms of the GNU Lesser General Public
11 //    License version 3, modified in accordance with the provisions
12 //    of the license to address the requirements of UK law.
13 //
14 //    You should have received a copy of the modified GNU Lesser
15 //    General Public License along with this library. If not, copies
16 //    may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
17 //
18 //    This program is distributed in the hope that it will be useful,
19 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 //    GNU Lesser General Public License for more details.
22 //
23 //  =================================================================
24 //
25 //    12.09.13   <--  Date of Last Modification.
26 //                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 //  -----------------------------------------------------------------
28 //
29 //  **** Module  :   MMDBF_Mask <implementation>
30 //       ~~~~~~~~~
31 //  **** Project :   MacroMolecular Data Base (MMDB)
32 //       ~~~~~~~~~
33 //
34 //  **** Classes :   mmdb::Mask  ( atom selection mask )
35 //       ~~~~~~~~~
36 //
37 //  (C) E. Krissinel 2000-2013
38 //
39 //  =================================================================
40 //
41 
42 #include <string.h>
43 #include <stdlib.h>
44 
45 #include "mmdb_mask.h"
46 
47 namespace mmdb  {
48 
49   //  ====================  Mask  ========================
50 
Mask()51   Mask::Mask() : io::Stream()  {
52     InitMask();
53   }
54 
Mask(io::RPStream Object)55   Mask::Mask ( io::RPStream Object ) : io::Stream(Object)  {
56     InitMask();
57   }
58 
~Mask()59   Mask::~Mask()  {
60     ClearMask();
61   }
62 
InitMask()63   void Mask::InitMask()  {
64     mlen = 0;
65     m    = NULL;
66   }
67 
SetMaskBit(int BitNo)68   void Mask::SetMaskBit ( int BitNo )  {
69   int n,i;
70     n = BitNo/(8*sizeof(word));
71     Expand ( n+1 );
72     i = BitNo - n*(8*sizeof(word));
73     m[n] |= ((word)1 << i);
74   }
75 
Expand(int n)76   void Mask::Expand ( int n )  {
77   wvector m1;
78   int     i;
79     if (mlen<n)  {
80       m1 = new word[n];
81       for (i=0;i<mlen;i++)
82         m1[i] = m[i];
83       for (i=mlen;i<n;i++)
84         m1[i] = 0;
85       if (m)  delete[] m;
86       m    = m1;
87       mlen = n;
88     }
89   }
90 
NewMask(PPMask Mask,int nMasks)91   void  Mask::NewMask ( PPMask Mask, int nMasks )  {
92   int  i,nlen;
93   word w;
94     ClearMask();
95     if (Mask && (nMasks>0))  {
96       nlen = 0;
97       w    = 0;
98       while (w==0)  {
99         for (i=0;i<nMasks;i++)
100           if (Mask[i])  {
101             if (nlen<Mask[i]->mlen)
102               w |= Mask[i]->m[nlen];
103           }
104         nlen++;
105         w = ~w;
106       }
107       Expand ( nlen );
108       i    = nlen-1;
109       m[i] = 1;
110       while (!(m[i] & w))
111         m[i] <<= 1;
112     } else  {
113       Expand ( 1 );
114       m[0] = 1;
115     }
116   }
117 
CopyMask(PMask Mask)118   void  Mask::CopyMask ( PMask Mask )  {
119   int i;
120     if (mlen!=Mask->mlen)  ClearMask();
121     if (Mask)  {
122       mlen = Mask->mlen;
123       if (mlen>0)  {
124         m = new word[mlen];
125         for (i=0;i<mlen;i++)
126           m[i] = Mask->m[i];
127       }
128     }
129   }
130 
SetMask(PMask Mask)131   void  Mask::SetMask ( PMask Mask )  {
132   int i;
133     if (Mask) {
134       Expand ( Mask->mlen );
135       for (i=0;i<Mask->mlen;i++)
136         m[i] |= Mask->m[i];
137     }
138   }
139 
RemoveMask(PMask Mask)140   void  Mask::RemoveMask ( PMask Mask )  {
141   int i,l;
142     if (Mask) {
143       l = IMin(mlen,Mask->mlen);
144       for (i=0;i<l;i++)
145         m[i] &= ~Mask->m[i];
146     }
147   }
148 
SelMask(PMask Mask)149   void  Mask::SelMask ( PMask Mask )  {
150   int i,l;
151     if (Mask)  {
152       l = IMin(mlen,Mask->mlen);
153       for (i=0;i<l;i++)
154         m[i] &= Mask->m[i];
155       for (i=l;i<mlen;i++)
156         m[i] = 0;
157     } else
158       ClearMask();
159   }
160 
XadMask(PMask Mask)161   void  Mask::XadMask ( PMask Mask )  {
162   int i;
163     if (Mask) {
164       Expand ( Mask->mlen );
165       for (i=0;i<Mask->mlen;i++)
166         m[i] ^= Mask->m[i];
167     }
168   }
169 
ClearMask()170   void  Mask::ClearMask()  {
171     if (m)  delete[] m;
172     m = NULL;
173     mlen = 0;
174   }
175 
NegMask()176   void  Mask::NegMask()  {
177   int i;
178     for (i=0;i<mlen;i++)
179       m[i] = ~m[i];
180   }
181 
CheckMask(PMask Mask)182   bool  Mask::CheckMask ( PMask Mask )  {
183   int i,l;
184     if (Mask)  {
185       i = 0;
186       l = IMin(mlen,Mask->mlen);
187       while ((i<l) && (!(m[i] & Mask->m[i])))  i++;
188       return (i<l);
189     } else
190       return false;
191   }
192 
isMask()193   bool  Mask::isMask()  {
194   int i=0;
195     while ((i<mlen) && (!m[i]))  i++;
196     return (i<mlen);
197   }
198 
Print(pstr S)199   pstr  Mask::Print ( pstr S )  {
200   int  i,j,k;
201   word w;
202     j = 0;
203     for (i=0;i<mlen;i++)  {
204       w = 1;
205       for (k=0;k<8*(int)sizeof(word);k++)  {
206         if (w & m[i])  S[j] = '1';
207                  else  S[j] = '0';
208         w <<= 1;
209         j++;
210       }
211     }
212     S[j] = char(0);
213     return S;
214   }
215 
write(io::RFile f)216   void  Mask::write ( io::RFile f )  {
217   int i;
218     f.WriteInt ( &mlen );
219     for (i=0;i<mlen;i++)
220       f.WriteWord ( &(m[i]) );
221   }
222 
read(io::RFile f)223   void  Mask::read ( io::RFile f )  {
224   int i;
225     if (m)  {
226       delete[] m;
227       m = NULL;
228     }
229     f.ReadInt ( &mlen );
230     if (mlen>0)  {
231       m = new word[mlen];
232       for (i=0;i<mlen;i++)
233         f.ReadWord ( &(m[i]) );
234     }
235   }
236 
237   MakeStreamFunctions(Mask)
238 
239 }  // namespace mmdb
240 
241