@@ -79,10 +79,10 @@ def __init__(self, sv, tool_window):
79
79
ur_layout .addWidget (self .use_region_check_box , alignment = Qt .AlignLeft , stretch = 1 )
80
80
layout .addLayout (ur_layout )
81
81
82
- # cr_layout = QHBoxLayout()
83
- # self.create_region_check_box = QCheckBox("Create region showing matched residues")
84
- # cr_layout.addWidget(self.create_region_check_box, alignment=Qt.AlignLeft, stretch=1)
85
- # layout.addLayout(cr_layout)
82
+ cr_layout = QHBoxLayout ()
83
+ self .create_region_check_box = QCheckBox ("Create region showing matched residues" )
84
+ cr_layout .addWidget (self .create_region_check_box , alignment = Qt .AlignLeft , stretch = 1 )
85
+ layout .addLayout (cr_layout )
86
86
87
87
from Qt .QtWidgets import QDialogButtonBox as qbbox
88
88
bbox = qbbox (qbbox .Ok | qbbox .Apply | qbbox .Close | qbbox .Help )
@@ -139,9 +139,61 @@ def match(self, *, apply=False):
139
139
if not apply :
140
140
self .tool_window .shown = False
141
141
from chimerax .core .commands import run , StringArg
142
- results = run (self .sv .session , "seq match %s %s to %s%s"
143
- % (StringArg .unparse (self .sv .alignment .ident ), ref . atomspec ,
144
- ', ' .join ([c .atomspec for c in matches ]), args ))
142
+ results = run (self .sv .session , "seq match %s %s to %s%s" %
143
+ (StringArg .unparse (self .sv .alignment .ident ),
144
+ '' .join ([c .atomspec for c in matches ]), ref . atomspec , args ))
145
145
146
146
if self .create_region_check_box .isChecked ():
147
- pass #TODO
147
+ def get_info (a , aln = self .sv .alignment ):
148
+ r = a .residue
149
+ c = r .chain
150
+ aseq = aln .associations [c ]
151
+ mmap = aseq .match_maps [c ]
152
+ return aseq , aseq .ungapped_to_gapped (mmap [r ])
153
+ region_indices = { seq : set () for seq in self .sv .alignment .seqs }
154
+ for match_atoms , ref_atoms , rmsd , full_rmsd , xform in results :
155
+ if match_atoms is None :
156
+ continue
157
+ for atoms in (match_atoms , ref_atoms ):
158
+ for a in atoms :
159
+ aseq , index = get_info (a )
160
+ region_indices [aseq ].add (index )
161
+ region_blocks = []
162
+ seqs = self .sv .alignment .seqs
163
+ while seqs :
164
+ aseq = seqs .pop (0 )
165
+ aseq_indices = region_indices .pop (aseq )
166
+ if not aseq_indices :
167
+ continue
168
+ collate (aseq , aseq_indices , region_indices , seqs , region_blocks )
169
+ if not region_blocks :
170
+ self .sv .sesson .logger .warn ("No matching occurred; not creating 'match' region" )
171
+ reg_name , fill , outline = self .sv .MATCHED_REGION_INFO
172
+ reg = self .sv .region_manager .get_region (reg_name , fill = fill , outline = outline , create = True ,
173
+ cover_gaps = True )
174
+ reg .clear ()
175
+ reg .add_blocks (region_blocks )
176
+
177
+ def collate (aseq , aseq_indices , region_indices , seqs , region_blocks ):
178
+ while aseq_indices :
179
+ first_i = last_i = min (aseq_indices )
180
+ while last_i + 1 in aseq_indices :
181
+ last_i += 1
182
+ first_seq = last_seq = aseq
183
+ for seq in seqs :
184
+ seq_indices = region_indices [seq ]
185
+ for i in range (first_i , last_i + 1 ):
186
+ if i not in seq_indices :
187
+ break
188
+ else :
189
+ last_seq = seq
190
+ continue
191
+ break
192
+ region_blocks .append ((first_seq , last_seq , first_i , last_i ))
193
+ for i in range (first_i , last_i + 1 ):
194
+ aseq_indices .remove (i )
195
+ if last_seq != aseq :
196
+ for seq in seqs :
197
+ region_indices [seq ].remove (i )
198
+ if seq == last_seq :
199
+ break
0 commit comments