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