1 /* @source ensmapper **********************************************************
2 **
3 ** Ensembl Mapper functions
4 **
5 ** @author Copyright (C) 1999 Ensembl Developers
6 ** @author Copyright (C) 2006 Michael K. Schuster
7 ** @version $Revision: 1.52 $
8 ** @modified 2009 by Alan Bleasby for incorporation into EMBOSS core
9 ** @modified $Date: 2013/02/17 13:02:40 $ by $Author: mks $
10 ** @@
11 **
12 ** This library is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU Lesser General Public
14 ** License as published by the Free Software Foundation; either
15 ** version 2.1 of the License, or (at your option) any later version.
16 **
17 ** This library is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ** Lesser General Public License for more details.
21 **
22 ** You should have received a copy of the GNU Lesser General Public
23 ** License along with this library; if not, write to the Free Software
24 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 ** MA  02110-1301,  USA.
26 **
27 ******************************************************************************/
28 
29 /* ========================================================================= */
30 /* ============================= include files ============================= */
31 /* ========================================================================= */
32 
33 #include "ensmapper.h"
34 #include "enstable.h"
35 
36 
37 
38 
39 /* ========================================================================= */
40 /* =============================== constants =============================== */
41 /* ========================================================================= */
42 
43 
44 
45 
46 /* ========================================================================= */
47 /* =========================== global variables ============================ */
48 /* ========================================================================= */
49 
50 
51 
52 
53 /* ========================================================================= */
54 /* ============================= private data ============================== */
55 /* ========================================================================= */
56 
57 
58 
59 
60 /* ========================================================================= */
61 /* =========================== private constants =========================== */
62 /* ========================================================================= */
63 
64 
65 
66 
67 /* ========================================================================= */
68 /* =========================== private variables =========================== */
69 /* ========================================================================= */
70 
71 
72 
73 
74 /* ========================================================================= */
75 /* =========================== private functions =========================== */
76 /* ========================================================================= */
77 
78 static int listMapperpairCompareSourceStartAscending(
79     const void *item1,
80     const void *item2);
81 
82 static int listMapperpairCompareTargetStartAscending(
83     const void *item1,
84     const void *item2);
85 
86 static void mapperrangeregistryListMapperrangeValdel(void **Pvalue);
87 
88 static void mapperListMapperpairValdel(void **Pvalue);
89 
90 static void mapperMapperpairsClear(const void *key,
91                                    void **Pvalue,
92                                    void *cl);
93 
94 static AjBool mapperMapperpairsMerge(EnsPMapper mapper);
95 
96 static AjBool mapperMapperpairsSort(EnsPMapper mapper);
97 
98 static AjBool mapperMapInsert(EnsPMapper mapper,
99                               ajuint oid,
100                               ajint start,
101                               ajint end,
102                               ajint strand,
103                               const AjPStr type,
104                               AjBool fastmap,
105                               AjPList mrs);
106 
107 
108 
109 
110 /* ========================================================================= */
111 /* ======================= All functions by section ======================== */
112 /* ========================================================================= */
113 
114 
115 
116 
117 /* @filesection ensmapper *****************************************************
118 **
119 ** @nam1rule ens Function belongs to the Ensembl library
120 **
121 ******************************************************************************/
122 
123 
124 
125 
126 /* @datasection [EnsPMapperunit] Ensembl Mapper Unit **************************
127 **
128 ** @nam2rule Mapperunit Functions for manipulating Ensembl Mapper Unit objects
129 **
130 ** @cc Bio::EnsEMBL::Mapper::Unit
131 ** @cc CVS Revision: 1.12
132 ** @cc CVS Tag: branch-ensembl-68
133 **
134 ******************************************************************************/
135 
136 
137 
138 
139 /* @section constructors ******************************************************
140 **
141 ** All constructors return a new Ensembl Mapper Unit by pointer.
142 ** It is the responsibility of the user to first destroy any previous
143 ** Mapper Unit. The target pointer does not need to be initialised to
144 ** NULL, but it is good programming practice to do so anyway.
145 **
146 ** @fdata [EnsPMapperunit]
147 **
148 ** @nam3rule New Constructor
149 ** @nam4rule Cpy Constructor with existing object
150 ** @nam4rule Ini Constructor with initial values
151 ** @nam4rule Ref Constructor by incrementing the reference counter
152 **
153 ** @argrule Cpy mu [const EnsPMapperunit] Ensembl Mapper Unit
154 ** @argrule Ini oid [ajuint] Ensembl Object identifier
155 ** @argrule Ini start [ajint] Start coordinate
156 ** @argrule Ini end [ajint] End coordinate
157 ** @argrule Ref mu [EnsPMapperunit] Ensembl Mapper Unit
158 **
159 ** @valrule * [EnsPMapperunit] Ensembl Mapper Unit or NULL
160 **
161 ** @fcategory new
162 ******************************************************************************/
163 
164 
165 
166 
167 /* @func ensMapperunitNewCpy **************************************************
168 **
169 ** Object-based constructor function, which returns an independent object.
170 **
171 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
172 **
173 ** @return [EnsPMapperunit] Ensembl Mapper Unit or NULL
174 **
175 ** @release 6.4.0
176 ** @@
177 ******************************************************************************/
178 
ensMapperunitNewCpy(const EnsPMapperunit mu)179 EnsPMapperunit ensMapperunitNewCpy(const EnsPMapperunit mu)
180 {
181     EnsPMapperunit pthis = NULL;
182 
183     if (!mu)
184         return NULL;
185 
186     AJNEW0(pthis);
187 
188     pthis->Objectidentifier = mu->Objectidentifier;
189 
190     pthis->Start = mu->Start;
191     pthis->End   = mu->End;
192     pthis->Use   = 1U;
193 
194     return pthis;
195 }
196 
197 
198 
199 
200 /* @func ensMapperunitNewIni **************************************************
201 **
202 ** Constructor for an Ensembl Mapper Unit with initial values.
203 **
204 ** @cc Bio::EnsEMBL::Mapper::Unit::new
205 ** @param [r] oid [ajuint] Ensembl Object identifier
206 ** @param [r] start [ajint] Start coordinate
207 ** @param [r] end [ajint] End coordinate
208 **
209 ** @return [EnsPMapperunit] Ensembl Mapper Unit or NULL
210 **
211 ** @release 6.4.0
212 ** @@
213 ******************************************************************************/
214 
ensMapperunitNewIni(ajuint oid,ajint start,ajint end)215 EnsPMapperunit ensMapperunitNewIni(ajuint oid, ajint start, ajint end)
216 {
217     EnsPMapperunit mu = NULL;
218 
219     if (!oid)
220         return NULL;
221 
222     AJNEW0(mu);
223 
224     mu->Objectidentifier = oid;
225 
226     mu->Start = start;
227     mu->End   = end;
228     mu->Use   = 1U;
229 
230     return mu;
231 }
232 
233 
234 
235 
236 /* @func ensMapperunitNewRef **************************************************
237 **
238 ** Ensembl Object referencing function, which returns a pointer to the
239 ** Ensembl Object passed in and increases its reference count.
240 **
241 ** @param [u] mu [EnsPMapperunit] Ensembl Mapper Unit
242 **
243 ** @return [EnsPMapperunit] Ensembl Mapper Unit or NULL
244 **
245 ** @release 6.2.0
246 ** @@
247 ******************************************************************************/
248 
ensMapperunitNewRef(EnsPMapperunit mu)249 EnsPMapperunit ensMapperunitNewRef(EnsPMapperunit mu)
250 {
251     if (!mu)
252         return NULL;
253 
254     mu->Use++;
255 
256     return mu;
257 }
258 
259 
260 
261 
262 /* @section destructors *******************************************************
263 **
264 ** Destruction destroys all internal data structures and frees the memory
265 ** allocated for an Ensembl Mapper Unit object.
266 **
267 ** @fdata [EnsPMapperunit]
268 **
269 ** @nam3rule Del Destroy (free) an Ensembl Mapper Unit
270 **
271 ** @argrule * Pmu [EnsPMapperunit*] Ensembl Mapper Unit address
272 **
273 ** @valrule * [void]
274 **
275 ** @fcategory delete
276 ******************************************************************************/
277 
278 
279 
280 
281 /* @func ensMapperunitDel *****************************************************
282 **
283 ** Default destructor for an Ensembl Mapper Unit.
284 **
285 ** @param [d] Pmu [EnsPMapperunit*] Ensembl Mapper Unit address
286 **
287 ** @return [void]
288 **
289 ** @release 6.2.0
290 ** @@
291 ******************************************************************************/
292 
ensMapperunitDel(EnsPMapperunit * Pmu)293 void ensMapperunitDel(EnsPMapperunit *Pmu)
294 {
295     EnsPMapperunit pthis = NULL;
296 
297     if (!Pmu)
298         return;
299 
300 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
301     if (ajDebugTest("ensMapperunitDel"))
302     {
303         ajDebug("ensMapperunitDel\n"
304                 "  *Pmu %p\n",
305                 *Pmu);
306 
307         ensMapperunitTrace(*Pmu, 1);
308     }
309 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
310 
311     if (!(pthis = *Pmu) || --pthis->Use)
312     {
313         *Pmu = NULL;
314 
315         return;
316     }
317 
318     ajMemFree((void **) Pmu);
319 
320     return;
321 }
322 
323 
324 
325 
326 /* @section member retrieval **************************************************
327 **
328 ** Functions for returning members of an Ensembl Mapper Unit object.
329 **
330 ** @fdata [EnsPMapperunit]
331 **
332 ** @nam3rule Get Return Ensembl Mapper Unit attribute(s)
333 ** @nam4rule End Return the end coordinate
334 ** @nam4rule Objectidentifier Return the Ensembl Object identifier
335 ** @nam4rule Start Return the start coordinate
336 **
337 ** @argrule * mu [const EnsPMapperunit] Ensembl Mapper Unit
338 **
339 ** @valrule End [ajint] End coordinate or 0
340 ** @valrule Objectidentifier [ajuint] Ensembl Object identifier or 0U
341 ** @valrule Start [ajint] Start coordinate or 0
342 **
343 ** @fcategory use
344 ******************************************************************************/
345 
346 
347 
348 
349 /* @func ensMapperunitGetEnd **************************************************
350 **
351 ** Get the end coordinate member of an Ensembl Mapper Unit.
352 **
353 ** @cc Bio::EnsEMBL::Mapper::Unit::end
354 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
355 **
356 ** @return [ajint] End coordinate or 0
357 **
358 ** @release 6.2.0
359 ** @@
360 ******************************************************************************/
361 
ensMapperunitGetEnd(const EnsPMapperunit mu)362 ajint ensMapperunitGetEnd(const EnsPMapperunit mu)
363 {
364     return (mu) ? mu->End : 0;
365 }
366 
367 
368 
369 
370 /* @func ensMapperunitGetObjectidentifier *************************************
371 **
372 ** Get the Ensembl Object identifier member of an Ensembl Mapper Unit.
373 **
374 ** @cc Bio::EnsEMBL::Mapper::Unit::id
375 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
376 **
377 ** @return [ajuint] Ensembl Object identifier or 0U
378 **
379 ** @release 6.4.0
380 ** @@
381 ******************************************************************************/
382 
ensMapperunitGetObjectidentifier(const EnsPMapperunit mu)383 ajuint ensMapperunitGetObjectidentifier(const EnsPMapperunit mu)
384 {
385     return (mu) ? mu->Objectidentifier : 0U;
386 }
387 
388 
389 
390 
391 /* @func ensMapperunitGetStart ************************************************
392 **
393 ** Get the start coordinate member of an Ensembl Mapper Unit.
394 **
395 ** @cc Bio::EnsEMBL::Mapper::Unit::start
396 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
397 **
398 ** @return [ajint] Start coordinate or 0
399 **
400 ** @release 6.2.0
401 ** @@
402 ******************************************************************************/
403 
ensMapperunitGetStart(const EnsPMapperunit mu)404 ajint ensMapperunitGetStart(const EnsPMapperunit mu)
405 {
406     return (mu) ? mu->Start : 0;
407 }
408 
409 
410 
411 
412 /* @section modifiers *********************************************************
413 **
414 ** Functions for assigning members of an Ensembl Mapper Unit object.
415 **
416 ** @fdata [EnsPMapperunit]
417 **
418 ** @nam3rule Set Set one member of an Ensembl Mapper Unit
419 ** @nam4rule End Set the end coordinate
420 ** @nam4rule Objectidentifier Set the Ensembl Object identifier
421 ** @nam4rule Start Set the start coordinate
422 **
423 ** @argrule * mu [EnsPMapperunit] Ensembl Mapper Unit object
424 ** @argrule End end [ajint] End coordinate
425 ** @argrule Objectidentifier oid [ajuint] Ensembl Object identifier
426 ** @argrule Start start [ajint] Start coordinate
427 **
428 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
429 **
430 ** @fcategory modify
431 ******************************************************************************/
432 
433 
434 
435 
436 /* @func ensMapperunitSetEnd **************************************************
437 **
438 ** Set the end coordinate member of an Ensembl Mapper Unit.
439 **
440 ** @cc Bio::EnsEMBL::Mapper::Unit::end
441 ** @param [u] mu [EnsPMapperunit] Ensembl Mapper Unit
442 ** @param [r] end [ajint] End coordinate
443 **
444 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
445 **
446 ** @release 6.2.0
447 ** @@
448 ******************************************************************************/
449 
ensMapperunitSetEnd(EnsPMapperunit mu,ajint end)450 AjBool ensMapperunitSetEnd(EnsPMapperunit mu, ajint end)
451 {
452     if (!mu)
453         return ajFalse;
454 
455     mu->End = end;
456 
457     return ajTrue;
458 }
459 
460 
461 
462 
463 /* @func ensMapperunitSetObjectidentifier *************************************
464 **
465 ** Set the Ensembl Object identifier member of an Ensembl Mapper Unit.
466 **
467 ** @cc Bio::EnsEMBL::Mapper::Unit::id
468 ** @param [u] mu [EnsPMapperunit] Ensembl Mapper Unit
469 ** @param [r] oid [ajuint] Ensembl Object identifier
470 **
471 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
472 **
473 ** @release 6.4.0
474 ** @@
475 ******************************************************************************/
476 
ensMapperunitSetObjectidentifier(EnsPMapperunit mu,ajuint oid)477 AjBool ensMapperunitSetObjectidentifier(EnsPMapperunit mu, ajuint oid)
478 {
479     if (!mu)
480         return ajFalse;
481 
482     if (!oid)
483         return ajFalse;
484 
485     mu->Objectidentifier = oid;
486 
487     return ajTrue;
488 }
489 
490 
491 
492 
493 /* @func ensMapperunitSetStart ************************************************
494 **
495 ** Set the start coordinate member of an Ensembl Mapper Unit.
496 **
497 ** @cc Bio::EnsEMBL::Mapper::Unit::start
498 ** @param [u] mu [EnsPMapperunit] Ensembl Mapper Unit
499 ** @param [r] start [ajint] Start coordinate
500 **
501 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
502 **
503 ** @release 6.2.0
504 ** @@
505 ******************************************************************************/
506 
ensMapperunitSetStart(EnsPMapperunit mu,ajint start)507 AjBool ensMapperunitSetStart(EnsPMapperunit mu, ajint start)
508 {
509     if (!mu)
510         return ajFalse;
511 
512     mu->Start = start;
513 
514     return ajTrue;
515 }
516 
517 
518 
519 
520 /* @section debugging *********************************************************
521 **
522 ** Functions for reporting of an Ensembl Mapper Unit object.
523 **
524 ** @fdata [EnsPMapperunit]
525 **
526 ** @nam3rule Trace Report Ensembl Mapper Unit members to debug file
527 **
528 ** @argrule Trace mu [const EnsPMapperunit] Ensembl Mapper Unit
529 ** @argrule Trace level [ajuint] Indentation level
530 **
531 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
532 **
533 ** @fcategory misc
534 ******************************************************************************/
535 
536 
537 
538 
539 /* @func ensMapperunitTrace ***************************************************
540 **
541 ** Trace an Ensembl Mapper Unit.
542 **
543 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
544 ** @param [r] level [ajuint] Indentation level
545 **
546 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
547 **
548 ** @release 6.2.0
549 ** @@
550 ******************************************************************************/
551 
ensMapperunitTrace(const EnsPMapperunit mu,ajuint level)552 AjBool ensMapperunitTrace(const EnsPMapperunit mu, ajuint level)
553 {
554     AjPStr indent = NULL;
555 
556     if (!mu)
557         return ajFalse;
558 
559     indent = ajStrNew();
560 
561     ajStrAppendCountK(&indent, ' ', level * 2);
562 
563     ajDebug("%SensMapperunitTrace %p\n"
564             "%S  Objectidentifier %u\n"
565             "%S  Start %d\n"
566             "%S  End %d\n"
567             "%S  Use %u\n",
568             indent, mu,
569             indent, mu->Objectidentifier,
570             indent, mu->Start,
571             indent, mu->End,
572             indent, mu->Use);
573 
574     ajStrDel(&indent);
575 
576     return ajTrue;
577 }
578 
579 
580 
581 
582 /* @section calculate *********************************************************
583 **
584 ** Functions for calculating information from an Ensembl Mapper Unit object.
585 **
586 ** @fdata [EnsPMapperunit]
587 **
588 ** @nam3rule Calculate Calculate Ensembl Mapper Unit information
589 ** @nam4rule Memsize Calculate the memory size in bytes
590 **
591 ** @argrule * mu [const EnsPMapperunit] Ensembl Mapper Unit
592 **
593 ** @valrule Memsize [size_t] Memory size in bytes or 0
594 **
595 ** @fcategory misc
596 ******************************************************************************/
597 
598 
599 
600 
601 /* @func ensMapperunitCalculateMemsize ****************************************
602 **
603 ** Calculate the memory size in bytes of an Ensembl Mapper Unit.
604 **
605 ** @param [r] mu [const EnsPMapperunit] Ensembl Mapper Unit
606 **
607 ** @return [size_t] Memory size in bytes or 0
608 **
609 ** @release 6.4.0
610 ** @@
611 ******************************************************************************/
612 
ensMapperunitCalculateMemsize(const EnsPMapperunit mu)613 size_t ensMapperunitCalculateMemsize(const EnsPMapperunit mu)
614 {
615     size_t size = 0;
616 
617     if (!mu)
618         return 0;
619 
620     size += sizeof (EnsOMapperunit);
621 
622     return size;
623 }
624 
625 
626 
627 
628 /* @datasection [EnsPMapperpair] Ensembl Mapper Pair **************************
629 **
630 ** @nam2rule Mapperpair Functions for manipulating Ensembl Mapper Pair objects
631 **
632 ** @cc Bio::EnsEMBL::Mapper::IndelPair
633 ** @cc CVS Revision: 1.8
634 ** @cc CVS Tag: branch-ensembl-68
635 **
636 ** @cc Bio::EnsEMBL::Mapper::Pair
637 ** @cc CVS Revision: 1.13
638 ** @cc CVS Tag: branch-ensembl-68
639 **
640 ******************************************************************************/
641 
642 
643 
644 
645 /* @section constructors ******************************************************
646 **
647 ** All constructors return a new Ensembl Mapper Pair by pointer.
648 ** It is the responsibility of the user to first destroy any previous
649 ** Mapper Pair. The target pointer does not need to be initialised to
650 ** NULL, but it is good programming practice to do so anyway.
651 **
652 ** @fdata [EnsPMapperpair]
653 **
654 ** @nam3rule New Constructor
655 ** @nam4rule Cpy Constructor with existing object
656 ** @nam4rule Ini Constructor with initial values
657 ** @nam4rule Ref Constructor by incrementing the reference counter
658 ** @nam4rule Unit Constructor with Ensembl Mapper Unit objects
659 **
660 ** @argrule Cpy mp [const EnsPMapperpair] Ensembl Mapper Pair
661 ** @argrule Ini srcoid [ajuint] Source Ensembl Object identifier
662 ** @argrule Ini srcstart [ajint] Source Start coordinate
663 ** @argrule Ini srcend [ajint] Source End coordinate
664 ** @argrule Ini trgoid [ajuint] Target Ensembl Object identifier
665 ** @argrule Ini trgstart [ajint] Target Start coordinate
666 ** @argrule Ini trgend [ajint] Target End coordinate
667 ** @argrule Ini ori [ajint]
668 ** Relative orientation of the Ensembl Mapper Unit objects
669 ** @argrule ensMapperpairNewIni indel [AjBool] Insertion-deletion attribute
670 ** @argrule Unit source [EnsPMapperunit] Source Ensembl Mapper Unit
671 ** @argrule Unit target [EnsPMapperunit] Target Ensembl Mapper Unit
672 ** @argrule Unit ori [ajint]
673 ** Relative orientation of the Ensembl Mapper Unit objects
674 ** @argrule ensMapperpairNewUnit indel [AjBool] Insertion-deletion attribute
675 ** @argrule Ref mp [EnsPMapperpair] Ensembl Mapper Pair
676 **
677 ** @valrule * [EnsPMapperpair] Ensembl Mapper Pair or NULL
678 **
679 ** @fcategory new
680 ******************************************************************************/
681 
682 
683 
684 
685 /* @func ensMapperpairNewCpy **************************************************
686 **
687 ** Object-based constructor function, which returns an independent object.
688 **
689 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
690 **
691 ** @return [EnsPMapperpair] Ensembl Mapper Pair or NULL
692 **
693 ** @release 6.4.0
694 ** @@
695 ******************************************************************************/
696 
ensMapperpairNewCpy(const EnsPMapperpair mp)697 EnsPMapperpair ensMapperpairNewCpy(const EnsPMapperpair mp)
698 {
699     EnsPMapperpair pthis = NULL;
700 
701     if (!mp)
702         return NULL;
703 
704     AJNEW0(pthis);
705 
706     pthis->Source      = ensMapperunitNewCpy(mp->Source);
707     pthis->Target      = ensMapperunitNewCpy(mp->Target);
708     pthis->Orientation = mp->Orientation;
709     pthis->Indel       = mp->Indel;
710     pthis->Use         = 1U;
711 
712     return pthis;
713 }
714 
715 
716 
717 
718 /* @func ensMapperpairNewIni **************************************************
719 **
720 ** Construct an Ensembl Mapper Pair from components of Ensembl Mapper Unit
721 ** objects.
722 **
723 ** @param [r] srcoid [ajuint] Source Ensembl Object identifier
724 ** @param [r] srcstart [ajint] Source Start coordinate
725 ** @param [r] srcend [ajint] Source End coordinate
726 ** @param [r] trgoid [ajuint] Target Ensembl Object identifier
727 ** @param [r] trgstart [ajint] Target Start coordinate
728 ** @param [r] trgend [ajint] Target End coordinate
729 ** @param [r] ori [ajint]
730 ** Relative orientation of the Ensembl Mapper Unit objects
731 ** @param [r] indel [AjBool] Insertion-deletion attribute
732 **
733 ** @return [EnsPMapperpair] Ensembl Mapper Pair or NULL
734 **
735 ** @release 6.4.0
736 ** @@
737 ******************************************************************************/
738 
ensMapperpairNewIni(ajuint srcoid,ajint srcstart,ajint srcend,ajuint trgoid,ajint trgstart,ajint trgend,ajint ori,AjBool indel)739 EnsPMapperpair ensMapperpairNewIni(ajuint srcoid,
740                                    ajint srcstart,
741                                    ajint srcend,
742                                    ajuint trgoid,
743                                    ajint trgstart,
744                                    ajint trgend,
745                                    ajint ori,
746                                    AjBool indel)
747 {
748     EnsPMapperunit source = NULL;
749     EnsPMapperunit target = NULL;
750 
751     EnsPMapperpair mp = NULL;
752 
753     if (!srcoid)
754         return NULL;
755 
756     if (!trgoid)
757         return NULL;
758 
759     source = ensMapperunitNewIni(srcoid, srcstart, srcend);
760     target = ensMapperunitNewIni(trgoid, trgstart, trgend);
761 
762     mp = ensMapperpairNewUnit(source, target, ori, indel);
763 
764     ensMapperunitDel(&source);
765     ensMapperunitDel(&target);
766 
767     return mp;
768 }
769 
770 
771 
772 
773 /* @func ensMapperpairNewRef **************************************************
774 **
775 ** Ensembl Object referencing function, which returns a pointer to the
776 ** Ensembl Object passed in and increases its reference count
777 **
778 ** @param [u] mp [EnsPMapperpair] Ensembl Mapper Pair
779 **
780 ** @return [EnsPMapperpair] Ensembl Mapper Pair or NULL
781 **
782 ** @release 6.2.0
783 ** @@
784 ******************************************************************************/
785 
ensMapperpairNewRef(EnsPMapperpair mp)786 EnsPMapperpair ensMapperpairNewRef(EnsPMapperpair mp)
787 {
788     if (!mp)
789         return NULL;
790 
791     mp->Use++;
792 
793     return mp;
794 }
795 
796 
797 
798 
799 /* @func ensMapperpairNewUnit *************************************************
800 **
801 ** Constructor for an Ensembl Mapper Pair with Ensembl Mapper Unit objects.
802 **
803 ** @cc Bio::EnsEMBL::Mapper::Pair::new
804 ** @param [u] source [EnsPMapperunit] Source Ensembl Mapper Unit
805 ** @param [u] target [EnsPMapperunit] Target Ensembl Mapper Unit
806 ** @param [r] ori [ajint]
807 ** Relative orientation of the Ensembl Mapper Unit objects
808 ** @cc Bio::EnsEMBL::Mapper::IndelPair::new
809 ** @param [r] indel [AjBool] Insertion-deletion attribute
810 **
811 ** @return [EnsPMapperpair] Ensembl Mapper Pair or NULL
812 **
813 ** @release 6.4.0
814 ** @@
815 ******************************************************************************/
816 
ensMapperpairNewUnit(EnsPMapperunit source,EnsPMapperunit target,ajint ori,AjBool indel)817 EnsPMapperpair ensMapperpairNewUnit(EnsPMapperunit source,
818                                     EnsPMapperunit target,
819                                     ajint ori,
820                                     AjBool indel)
821 {
822     EnsPMapperpair mp = NULL;
823 
824     if (!source)
825         return NULL;
826 
827     if (!target)
828         return NULL;
829 
830     AJNEW0(mp);
831 
832     mp->Source      = ensMapperunitNewRef(source);
833     mp->Target      = ensMapperunitNewRef(target);
834     mp->Orientation = ori;
835     mp->Indel       = indel;
836     mp->Use         = 1U;
837 
838     return mp;
839 }
840 
841 
842 
843 
844 /* @section destructors *******************************************************
845 **
846 ** Destruction destroys all internal data structures and frees the memory
847 ** allocated for an Ensembl Mapper Pair object.
848 **
849 ** @fdata [EnsPMapperpair]
850 **
851 ** @nam3rule Del Destroy (free) an Ensembl Mapper Pair
852 **
853 ** @argrule * Pmp [EnsPMapperpair*] Ensembl Mapper Pair address
854 **
855 ** @valrule * [void]
856 **
857 ** @fcategory delete
858 ******************************************************************************/
859 
860 
861 
862 
863 /* @func ensMapperpairDel *****************************************************
864 **
865 ** Default destructor for an Ensembl Mapper Pair.
866 **
867 ** @param [d] Pmp [EnsPMapperpair*] Ensembl Mapper Pair address
868 **
869 ** @return [void]
870 **
871 ** @release 6.2.0
872 ** @@
873 ******************************************************************************/
874 
ensMapperpairDel(EnsPMapperpair * Pmp)875 void ensMapperpairDel(EnsPMapperpair *Pmp)
876 {
877     EnsPMapperpair pthis = NULL;
878 
879     if (!Pmp)
880         return;
881 
882 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
883     if (ajDebugTest("ensMapperpairDel"))
884     {
885         ajDebug("ensMapperpairDel\n"
886                 "  *Pmp %p\n",
887                 *Pmp);
888 
889         ensMapperpairTrace(*Pmp, 1);
890     }
891 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
892 
893     if (!(pthis = *Pmp) || --pthis->Use)
894     {
895         *Pmp = NULL;
896 
897         return;
898     }
899 
900     ensMapperunitDel(&pthis->Source);
901     ensMapperunitDel(&pthis->Target);
902 
903     ajMemFree((void **) Pmp);
904 
905     return;
906 }
907 
908 
909 
910 
911 /* @section member retrieval **************************************************
912 **
913 ** Functions for returning members of an Ensembl Mapper Pair object.
914 **
915 ** @fdata [EnsPMapperpair]
916 **
917 ** @nam3rule Get Return Ensembl Mapper Pair attribute(s)
918 ** @nam4rule Indel Return the insertion or deletion member
919 ** @nam4rule Orientation Return the orientation
920 ** @nam4rule Source Return the source Ensembl Mapper Unit
921 ** @nam4rule Target Return the target Ensembl Mapper Unit
922 **
923 ** @argrule * mp [const EnsPMapperpair] Ensembl Mapper Pair
924 **
925 ** @valrule Indel [AjBool] Insertion-deletion attribute
926 ** @valrule Orientation [ajint] Orientation or 0
927 ** @valrule Source [EnsPMapperunit] Ensembl Mapper Unit or NULL
928 ** @valrule Target [EnsPMapperunit] Ensembl Mapper Unit or NULL
929 **
930 ** @fcategory use
931 ******************************************************************************/
932 
933 
934 
935 
936 /* @func ensMapperpairGetIndel ************************************************
937 **
938 ** Return the insertion or deletion member of an Ensembl Mapper Pair.
939 **
940 ** @cc Bio::EnsEMBL::Mapper::IndelPair::???
941 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
942 **
943 ** @return [AjBool] ajTrue if this is an insertion or deletion
944 **
945 ** @release 6.4.0
946 ** @@
947 ******************************************************************************/
948 
ensMapperpairGetIndel(const EnsPMapperpair mp)949 AjBool ensMapperpairGetIndel(const EnsPMapperpair mp)
950 {
951     return (mp) ? mp->Indel : ajFalse;
952 }
953 
954 
955 
956 
957 /* @func ensMapperpairGetOrientation ******************************************
958 **
959 ** Get the relative orientation member of an Ensembl Mapper Pair.
960 **
961 ** @cc Bio::EnsEMBL::Mapper::Pair::ori
962 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
963 **
964 ** @return [ajint] Relative orientation or 0
965 **
966 ** @release 6.2.0
967 ** @@
968 ******************************************************************************/
969 
ensMapperpairGetOrientation(const EnsPMapperpair mp)970 ajint ensMapperpairGetOrientation(const EnsPMapperpair mp)
971 {
972     return (mp) ? mp->Orientation : 0;
973 }
974 
975 
976 
977 
978 /* @func ensMapperpairGetSource ***********************************************
979 **
980 ** Get the source Ensembl Mapper Unit member of an Ensembl Mapper Pair.
981 **
982 ** @cc Bio::EnsEMBL::Mapper::Pair::from
983 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
984 **
985 ** @return [EnsPMapperunit] Source Ensembl Mapper Unit or NULL
986 **
987 ** @release 6.2.0
988 ** @@
989 ******************************************************************************/
990 
ensMapperpairGetSource(const EnsPMapperpair mp)991 EnsPMapperunit ensMapperpairGetSource(const EnsPMapperpair mp)
992 {
993     return (mp) ? mp->Source : NULL;
994 }
995 
996 
997 
998 
999 /* @func ensMapperpairGetTarget ***********************************************
1000 **
1001 ** Get the Target Ensembl Mapper Unit member of an Ensembl Mapper Pair.
1002 **
1003 ** @cc Bio::EnsEMBL::Mapper::Pair::to
1004 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
1005 **
1006 ** @return [EnsPMapperunit] Target Ensembl Mapper Unit or NULL
1007 **
1008 ** @release 6.2.0
1009 ** @@
1010 ******************************************************************************/
1011 
ensMapperpairGetTarget(const EnsPMapperpair mp)1012 EnsPMapperunit ensMapperpairGetTarget(const EnsPMapperpair mp)
1013 {
1014     return (mp) ? mp->Target : NULL;
1015 }
1016 
1017 
1018 
1019 
1020 /* @section debugging *********************************************************
1021 **
1022 ** Functions for reporting of an Ensembl Mapper Pair object.
1023 **
1024 ** @fdata [EnsPMapperpair]
1025 **
1026 ** @nam3rule Trace Report Ensembl Mapper Pair members to debug file
1027 **
1028 ** @argrule Trace mp [const EnsPMapperpair] Ensembl Mapper Pair
1029 ** @argrule Trace level [ajuint] Indentation level
1030 **
1031 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
1032 **
1033 ** @fcategory misc
1034 ******************************************************************************/
1035 
1036 
1037 
1038 
1039 /* @func ensMapperpairTrace ***************************************************
1040 **
1041 ** Trace an Ensembl Mapper Pair.
1042 **
1043 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
1044 ** @param [r] level [ajuint] Indentation level
1045 **
1046 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1047 **
1048 ** @release 6.2.0
1049 ** @@
1050 ******************************************************************************/
1051 
ensMapperpairTrace(const EnsPMapperpair mp,ajuint level)1052 AjBool ensMapperpairTrace(const EnsPMapperpair mp, ajuint level)
1053 {
1054     AjPStr indent = NULL;
1055 
1056     if (!mp)
1057         return ajFalse;
1058 
1059     indent = ajStrNew();
1060 
1061     ajStrAppendCountK(&indent, ' ', level * 2);
1062 
1063     ajDebug("%SensMapperpairTrace %p\n"
1064             "%S  Source %p\n"
1065             "%S  Target %p\n"
1066             "%S  Orientation %d\n"
1067             "%S  Indel '%B'\n"
1068             "%S  Use %u\n",
1069             indent, mp,
1070             indent, mp->Source,
1071             indent, mp->Target,
1072             indent, mp->Orientation,
1073             indent, mp->Indel,
1074             indent, mp->Use);
1075 
1076     ensMapperunitTrace(mp->Source, level + 1);
1077     ensMapperunitTrace(mp->Target, level + 1);
1078 
1079     ajStrDel(&indent);
1080 
1081     return ajTrue;
1082 }
1083 
1084 
1085 
1086 
1087 /* @section calculate *********************************************************
1088 **
1089 ** Functions for calculating information from an Ensembl Mapper Pair object.
1090 **
1091 ** @fdata [EnsPMapperpair]
1092 **
1093 ** @nam3rule Calculate Calculate Ensembl Mapper Pair information
1094 ** @nam4rule Mapperunit Calculate the Ensembl Mapper Unit
1095 ** @nam4rule Memsize Calculate the memory size in bytes
1096 **
1097 ** @argrule * mp [const EnsPMapperpair] Ensembl Mapper Pair
1098 ** @argrule Mapperunit type [EnsEMapperunitType] Ensembl Mapper Unit Type
1099 **
1100 ** @valrule Mapperunit [EnsPMapperunit] Ensembl Mapper Unit or NULL
1101 ** @valrule Memsize [size_t] Memory size in bytes or 0
1102 **
1103 ** @fcategory misc
1104 ******************************************************************************/
1105 
1106 
1107 
1108 
1109 /* @func ensMapperpairCalculateMapperunit *************************************
1110 **
1111 ** Calculate the Ensembl Mapper Unit member of an Ensembl Mapper Pair via an
1112 ** Ensembl Mapper Unit Type enumeration.
1113 **
1114 ** @cc Bio::EnsEMBL::Mapper::Pair::from
1115 ** @cc Bio::EnsEMBL::Mapper::Pair::to
1116 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
1117 ** @param [u] type [EnsEMapperunitType] Ensembl Mapper Unit Type
1118 **
1119 ** @return [EnsPMapperunit] Source or Target Ensembl Mapper Unit or NULL
1120 **
1121 ** @release 6.4.0
1122 ** @@
1123 ******************************************************************************/
1124 
ensMapperpairCalculateMapperunit(const EnsPMapperpair mp,EnsEMapperunitType type)1125 EnsPMapperunit ensMapperpairCalculateMapperunit(const EnsPMapperpair mp,
1126                                                 EnsEMapperunitType type)
1127 {
1128     if (!mp)
1129         return NULL;
1130 
1131     if (!type)
1132         return NULL;
1133 
1134     switch (type)
1135     {
1136         case ensEMapperunitTypeSource:
1137             return mp->Source;
1138         case ensEMapperunitTypeTarget:
1139             return mp->Target;
1140         default:
1141             ajWarn("ensMapperpairCalculateMapperunit got unexpected "
1142                    "Ensembl Mapper Unit Type enumeration %d.\n", type);
1143     }
1144 
1145     return NULL;
1146 }
1147 
1148 
1149 
1150 
1151 /* @func ensMapperpairCalculateMemsize ****************************************
1152 **
1153 ** Calculate the memory size in bytes of an Ensembl Mapper Pair.
1154 **
1155 ** @param [r] mp [const EnsPMapperpair] Ensembl Mapper Pair
1156 **
1157 ** @return [size_t] Memory size in bytes or 0
1158 **
1159 ** @release 6.4.0
1160 ** @@
1161 ******************************************************************************/
1162 
ensMapperpairCalculateMemsize(const EnsPMapperpair mp)1163 size_t ensMapperpairCalculateMemsize(const EnsPMapperpair mp)
1164 {
1165     size_t size = 0;
1166 
1167     if (!mp)
1168         return 0;
1169 
1170     size += sizeof (EnsOMapperpair);
1171 
1172     size += ensMapperunitCalculateMemsize(mp->Source);
1173     size += ensMapperunitCalculateMemsize(mp->Target);
1174 
1175     return size;
1176 }
1177 
1178 
1179 
1180 
1181 /* @datasection [AjPList] AJAX List *******************************************
1182 **
1183 ** @nam2rule List Functions for manipulating AJAX List objects
1184 **
1185 ******************************************************************************/
1186 
1187 
1188 
1189 
1190 /* @section list **************************************************************
1191 **
1192 ** Functions for manipulating AJAX List objects.
1193 **
1194 ** @fdata [AjPList]
1195 **
1196 ** @nam3rule Mapperpair Functions for manipulating AJAX List objects of
1197 ** Ensembl Mapper Pair objects
1198 ** @nam4rule Sort Sort functions
1199 ** @nam5rule Source Sort by source Ensembl Mapper Unit
1200 ** @nam5rule Target Sort by target Ensembl Mapper Unit
1201 ** @nam6rule Start Sort by Ensembl Feature start member
1202 ** @nam7rule Ascending  Sort in ascending order
1203 ** @nam7rule Descending Sort in descending order
1204 **
1205 ** @argrule Ascending mps [AjPList] AJAX List of Ensembl Mapper Pair objects
1206 ** @argrule Descending mps [AjPList] AJAX List of Ensembl Mapper Pair objects
1207 **
1208 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
1209 **
1210 ** @fcategory misc
1211 ******************************************************************************/
1212 
1213 
1214 
1215 
1216 /* @funcstatic listMapperpairCompareSourceStartAscending **********************
1217 **
1218 ** AJAX List of Ensembl Mapper Pair objects comparison function to sort by
1219 ** source Ensembl Mapper Unit start coordinate in ascending order.
1220 **
1221 ** @param [r] item1 [const void*] Ensembl Mapper Pair address 1
1222 ** @param [r] item2 [const void*] Ensembl Mapper Pair address 2
1223 ** @see ajListSort
1224 **
1225 ** @return [int] The comparison function returns an integer less than,
1226 **               equal to, or greater than zero if the first argument is
1227 **               considered to be respectively less than, equal to, or
1228 **               greater than the second.
1229 **
1230 ** @release 6.4.0
1231 ** @@
1232 ******************************************************************************/
1233 
listMapperpairCompareSourceStartAscending(const void * item1,const void * item2)1234 static int listMapperpairCompareSourceStartAscending(
1235     const void *item1,
1236     const void *item2)
1237 {
1238     int result = 0;
1239 
1240     EnsPMapperpair mp1 = *(EnsOMapperpair *const *) item1;
1241     EnsPMapperpair mp2 = *(EnsOMapperpair *const *) item2;
1242 
1243 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
1244     if (ajDebugTest("listMapperpairCompareSourceStartAscending"))
1245     {
1246         ajDebug("listMapperpairCompareSourceStartAscending\n"
1247                 "  mp1 %p\n"
1248                 "  mp2 %p\n",
1249                 mp1,
1250                 mp2);
1251 
1252         ensMapperpairTrace(mp1, 1);
1253         ensMapperpairTrace(mp2, 1);
1254     }
1255 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
1256 
1257     /* Sort empty values towards the end of the AJAX List. */
1258 
1259     if (mp1 && (!mp2))
1260         return -1;
1261 
1262     if ((!mp1) && (!mp2))
1263         return 0;
1264 
1265     if ((!mp1) && mp2)
1266         return +1;
1267 
1268     /*
1269     ** Sort Ensembl Mapper Pair objects with empty source Ensembl Mapper Unit
1270     ** objects towards the end of the AJAX List.
1271     */
1272 
1273     if (mp1->Source && (!mp2->Source))
1274         return -1;
1275 
1276     if ((!mp1->Source) && (!mp2->Source))
1277         return 0;
1278 
1279     if ((!mp1->Source) && mp2->Source)
1280         return +1;
1281 
1282     /* Evaluate the Start coordinates of source Ensembl Mapper Unit objects. */
1283 
1284     if (mp1->Source->Start < mp2->Source->Start)
1285         result = -1;
1286 
1287     if (mp1->Source->Start > mp2->Source->Start)
1288         result = +1;
1289 
1290     return result;
1291 }
1292 
1293 
1294 
1295 
1296 /* @func ensListMapperpairSortSourceStartAscending ****************************
1297 **
1298 ** Sort an AJAX List of Ensembl Mapper Pair objects by their source
1299 ** Ensembl Mapper Unit start member in ascending order.
1300 **
1301 ** @param [u] mps [AjPList] AJAX List of Ensembl Mapper Pair objects
1302 **
1303 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1304 **
1305 ** @release 6.4.0
1306 ** @@
1307 ******************************************************************************/
1308 
ensListMapperpairSortSourceStartAscending(AjPList mps)1309 AjBool ensListMapperpairSortSourceStartAscending(AjPList mps)
1310 {
1311     if (!mps)
1312         return ajFalse;
1313 
1314     ajListSort(mps, &listMapperpairCompareSourceStartAscending);
1315 
1316     return ajTrue;
1317 }
1318 
1319 
1320 
1321 
1322 /* @funcstatic listMapperpairCompareTargetStartAscending **********************
1323 **
1324 ** AJAX List of Ensembl Mapper Pair objects comparison function to sort by
1325 ** target Ensembl Mapper Unit start coordinate in ascending order.
1326 **
1327 ** @param [r] item1 [const void*] Ensembl Mapper Pair address 1
1328 ** @param [r] item2 [const void*] Ensembl Mapper Pair address 2
1329 ** @see ajListSort
1330 **
1331 ** @return [int] The comparison function returns an integer less than,
1332 **               equal to, or greater than zero if the first argument is
1333 **               considered to be respectively less than, equal to, or
1334 **               greater than the second.
1335 **
1336 ** @release 6.4.0
1337 ** @@
1338 ******************************************************************************/
1339 
listMapperpairCompareTargetStartAscending(const void * item1,const void * item2)1340 static int listMapperpairCompareTargetStartAscending(
1341     const void *item1,
1342     const void *item2)
1343 {
1344     int result = 0;
1345 
1346     EnsPMapperpair mp1 = *(EnsOMapperpair *const *) item1;
1347     EnsPMapperpair mp2 = *(EnsOMapperpair *const *) item2;
1348 
1349 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
1350     if (ajDebugTest("listMapperpairCompareTargetStartAscending"))
1351     {
1352         ajDebug("listMapperpairCompareTargetStartAscending\n"
1353                 "  mp1 %p\n"
1354                 "  mp2 %p\n",
1355                 mp1,
1356                 mp2);
1357 
1358         ensMapperpairTrace(mp1, 1);
1359         ensMapperpairTrace(mp2, 1);
1360     }
1361 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
1362 
1363     /* Sort empty values towards the end of the AJAX List. */
1364 
1365     if (mp1 && (!mp2))
1366         return -1;
1367 
1368     if ((!mp1) && (!mp2))
1369         return 0;
1370 
1371     if ((!mp1) && mp2)
1372         return +1;
1373 
1374     /*
1375     ** Sort Ensembl Mapper Pair objects with empty target Ensembl Mapper Unit
1376     ** objects towards the end of the AJAX List.
1377     */
1378 
1379     if (mp1->Target && (!mp2->Target))
1380         return -1;
1381 
1382     if ((!mp1->Target) && (!mp2->Target))
1383         return 0;
1384 
1385     if ((!mp1->Target) && mp2->Target)
1386         return +1;
1387 
1388     /* Evaluate the Start coordinates of target Ensembl Mapper Unit objects. */
1389 
1390     if (mp1->Target->Start < mp2->Target->Start)
1391         result = -1;
1392 
1393     if (mp1->Target->Start > mp2->Target->Start)
1394         result = +1;
1395 
1396     return result;
1397 }
1398 
1399 
1400 
1401 
1402 /* @func ensListMapperpairSortTargetStartAscending ****************************
1403 **
1404 ** Sort an AJAX List of Ensembl Mapper Pair objects by their target
1405 ** Ensembl Mapper Unit start member in ascending order.
1406 **
1407 ** @param [u] mps [AjPList] AJAX List of Ensembl Mapper Pair objects
1408 **
1409 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1410 **
1411 ** @release 6.4.0
1412 ** @@
1413 ******************************************************************************/
1414 
ensListMapperpairSortTargetStartAscending(AjPList mps)1415 AjBool ensListMapperpairSortTargetStartAscending(AjPList mps)
1416 {
1417     if (!mps)
1418         return ajFalse;
1419 
1420     ajListSort(mps, &listMapperpairCompareTargetStartAscending);
1421 
1422     return ajTrue;
1423 }
1424 
1425 
1426 
1427 
1428 /* @datasection [EnsPMapperresult] Ensembl Mapper Result **********************
1429 **
1430 ** @nam2rule Mapperresult Functions for manipulating
1431 ** Ensembl Mapper Result objects
1432 **
1433 ** @cc Bio::EnsEMBL::Mapper::Coordinate
1434 ** @cc CVS Revision: 1.16
1435 ** @cc CVS Tag: branch-ensembl-68
1436 **
1437 ** @cc Bio::EnsEMBL::Mapper::Gap
1438 ** @cc CVS Revision: 1.14
1439 ** @cc CVS Tag: branch-ensembl-68
1440 **
1441 ** @cc Bio::EnsEMBL::Mapper::IndelCoordinate
1442 ** @cc CVS Revision: 1.9
1443 ** @cc CVS Tag: branch-ensembl-68
1444 **
1445 ******************************************************************************/
1446 
1447 
1448 
1449 
1450 /* @section constructors ******************************************************
1451 **
1452 ** All constructors return a new Ensembl Mapper Result by pointer.
1453 ** It is the responsibility of the user to first destroy any previous
1454 ** Mapper Result. The target pointer does not need to be initialised to
1455 ** NULL, but it is good programming practice to do so anyway.
1456 **
1457 ** @fdata [EnsPMapperresult]
1458 **
1459 ** @nam3rule New Constructor
1460 ** @nam4rule Coordinate Constructor for type ensEMapperresultTypeCoordinate
1461 ** @nam4rule Cpy Constructor with existing object
1462 ** @nam4rule Gap Constructor for type ensEMapperresultTypeGap
1463 ** @nam4rule Indel Constructor for type ensEMapperresultTypeInDel
1464 ** @nam4rule Ini Constructor with initial values
1465 ** @nam4rule Ref Constructor by incrementing the reference counter
1466 **
1467 ** @argrule Coordinate oid [ajuint] Ensembl Object identifier
1468 ** @argrule Coordinate crdstart [ajint] Start
1469 ** @argrule Coordinate crdend [ajint] End
1470 ** @argrule Coordinate crdstrand [ajint] Strand
1471 ** @argrule Coordinate cs [EnsPCoordsystem] Ensembl Coordinate System
1472 ** @argrule Coordinate rank [ajuint] Rank
1473 ** @argrule Cpy mr [const EnsPMapperresult] Ensembl Mapper Result
1474 ** @argrule Gap gapstart [ajint] Gap start
1475 ** @argrule Gap gapend [ajint] Gap end
1476 ** @argrule Gap rank [ajuint] Rank
1477 ** @argrule Indel oid [ajuint] Ensembl Object identifier
1478 ** @argrule Indel crdstart [ajint] Start
1479 ** @argrule Indel crdend [ajint] End
1480 ** @argrule Indel crdstrand [ajint] Strand
1481 ** @argrule Indel cs [EnsPCoordsystem] Ensembl Coordinate System
1482 ** @argrule Indel gapstart [ajint] Gap start
1483 ** @argrule Indel gapend [ajint] Gap end
1484 ** @argrule Indel rank [ajuint] Rank
1485 ** @argrule Ini type [EnsEMapperresultType] Type
1486 ** @argrule Ini oid [ajuint] Ensembl Object identifier
1487 ** @argrule Ini crdstart [ajint] Start
1488 ** @argrule Ini crdend [ajint] End
1489 ** @argrule Ini crdstrand [ajint] Strand
1490 ** @argrule Ini cs [EnsPCoordsystem] Ensembl Coordinate System
1491 ** @argrule Ini gapstart [ajint] Gap start
1492 ** @argrule Ini gapend [ajint] Gap end
1493 ** @argrule Ini rank [ajuint] Rank
1494 ** @argrule Ref mr [EnsPMapperresult] Ensembl Mapper Result
1495 **
1496 ** @valrule * [EnsPMapperresult] Ensembl Mapper Result or NULL
1497 **
1498 ** @fcategory new
1499 ******************************************************************************/
1500 
1501 
1502 
1503 
1504 /* @func ensMapperresultNewCoordinate *****************************************
1505 **
1506 ** Constructor for an Ensembl Mapper Result of type
1507 ** ensEMapperresultTypeCoordinate.
1508 **
1509 ** @param [r] oid [ajuint] Ensembl Object identifier
1510 ** @param [r] crdstart [ajint] Start
1511 ** @param [r] crdend [ajint] End
1512 ** @param [r] crdstrand [ajint] Strand
1513 ** @param [u] cs [EnsPCoordsystem] Ensembl Coordinate System
1514 ** @param [r] rank [ajuint] Rank
1515 **
1516 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1517 **
1518 ** @release 6.4.0
1519 ** @@
1520 ******************************************************************************/
1521 
ensMapperresultNewCoordinate(ajuint oid,ajint crdstart,ajint crdend,ajint crdstrand,EnsPCoordsystem cs,ajuint rank)1522 EnsPMapperresult ensMapperresultNewCoordinate(ajuint oid,
1523                                               ajint crdstart,
1524                                               ajint crdend,
1525                                               ajint crdstrand,
1526                                               EnsPCoordsystem cs,
1527                                               ajuint rank)
1528 {
1529     EnsPMapperresult mr = NULL;
1530 
1531     if (!oid)
1532         return NULL;
1533 
1534     if (!cs)
1535         return NULL;
1536 
1537     AJNEW0(mr);
1538 
1539     mr->Type             = ensEMapperresultTypeCoordinate;
1540     mr->Objectidentifier = oid;
1541     mr->CoordinateStart  = crdstart;
1542     mr->CoordinateEnd    = crdend;
1543     mr->CoordinateStrand = crdstrand;
1544     mr->Coordsystem      = ensCoordsystemNewRef(cs);
1545     mr->GapStart         = 0;
1546     mr->GapEnd           = 0;
1547     mr->Rank             = rank;
1548     mr->Use              = 1U;
1549 
1550     return mr;
1551 }
1552 
1553 
1554 
1555 
1556 /* @func ensMapperresultNewCpy ************************************************
1557 **
1558 ** Object-based constructor function, which returns an independent object.
1559 **
1560 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1561 **
1562 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1563 **
1564 ** @release 6.4.0
1565 ** @@
1566 ******************************************************************************/
1567 
ensMapperresultNewCpy(const EnsPMapperresult mr)1568 EnsPMapperresult ensMapperresultNewCpy(const EnsPMapperresult mr)
1569 {
1570     EnsPMapperresult pthis = NULL;
1571 
1572     if (!mr)
1573         return NULL;
1574 
1575     AJNEW0(pthis);
1576 
1577     pthis->Type             = mr->Type;
1578     pthis->Objectidentifier = mr->Objectidentifier;
1579     pthis->CoordinateStart  = mr->CoordinateStart;
1580     pthis->CoordinateEnd    = mr->CoordinateEnd;
1581     pthis->CoordinateStrand = mr->CoordinateStrand;
1582     pthis->Coordsystem      = ensCoordsystemNewRef(mr->Coordsystem);
1583     pthis->GapStart         = mr->GapStart;
1584     pthis->GapEnd           = mr->GapEnd;
1585     pthis->Rank             = mr->Rank;
1586     pthis->Use              = 1U;
1587 
1588     return pthis;
1589 }
1590 
1591 
1592 
1593 
1594 /* @func ensMapperresultNewGap ************************************************
1595 **
1596 ** Constructor for an Ensembl Mapper Result of type ensEMapperresultTypeGap.
1597 **
1598 ** @param [r] gapstart [ajint] Gap start
1599 ** @param [r] gapend [ajint] Gap end
1600 ** @param [r] rank [ajuint] Rank
1601 **
1602 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1603 **
1604 ** @release 6.4.0
1605 ** @@
1606 ******************************************************************************/
1607 
ensMapperresultNewGap(ajint gapstart,ajint gapend,ajuint rank)1608 EnsPMapperresult ensMapperresultNewGap(ajint gapstart,
1609                                        ajint gapend,
1610                                        ajuint rank)
1611 {
1612     EnsPMapperresult mr = NULL;
1613 
1614     AJNEW0(mr);
1615 
1616     mr->Type             = ensEMapperresultTypeGap;
1617     mr->Objectidentifier = 0;
1618     mr->CoordinateStart  = 0;
1619     mr->CoordinateEnd    = 0;
1620     mr->CoordinateStrand = 0;
1621     mr->Coordsystem      = NULL;
1622     mr->GapStart         = gapstart;
1623     mr->GapEnd           = gapend;
1624     mr->Rank             = rank;
1625     mr->Use              = 1U;
1626 
1627     return mr;
1628 }
1629 
1630 
1631 
1632 
1633 /* @func ensMapperresultNewIndel **********************************************
1634 **
1635 ** Constructor for an Ensembl Mapper Result of type
1636 ** ensEMapperresultTypeInDel.
1637 **
1638 ** @param [r] oid [ajuint] Ensembl Object identifier
1639 ** @param [r] crdstart [ajint] Start
1640 ** @param [r] crdend [ajint] End
1641 ** @param [r] crdstrand [ajint] Strand
1642 ** @param [u] cs [EnsPCoordsystem] Ensembl Coordinate System
1643 ** @param [r] gapstart [ajint] Gap start
1644 ** @param [r] gapend [ajint] Gap end
1645 ** @param [r] rank [ajuint] Rank
1646 **
1647 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1648 **
1649 ** @release 6.4.0
1650 ** @@
1651 ******************************************************************************/
1652 
ensMapperresultNewIndel(ajuint oid,ajint crdstart,ajint crdend,ajint crdstrand,EnsPCoordsystem cs,ajint gapstart,ajint gapend,ajuint rank)1653 EnsPMapperresult ensMapperresultNewIndel(ajuint oid,
1654                                          ajint crdstart,
1655                                          ajint crdend,
1656                                          ajint crdstrand,
1657                                          EnsPCoordsystem cs,
1658                                          ajint gapstart,
1659                                          ajint gapend,
1660                                          ajuint rank)
1661 {
1662     EnsPMapperresult mr = NULL;
1663 
1664     AJNEW0(mr);
1665 
1666     if (!oid)
1667         return NULL;
1668 
1669     if (!cs)
1670         return NULL;
1671 
1672     mr->Type             = ensEMapperresultTypeInDel;
1673     mr->Objectidentifier = oid;
1674     mr->CoordinateStart  = crdstart;
1675     mr->CoordinateEnd    = crdend;
1676     mr->CoordinateStrand = crdstrand;
1677     mr->Coordsystem      = ensCoordsystemNewRef(cs);
1678     mr->GapStart         = gapstart;
1679     mr->GapEnd           = gapend;
1680     mr->Rank             = rank;
1681     mr->Use              = 1U;
1682 
1683     return mr;
1684 }
1685 
1686 
1687 
1688 
1689 /* @func ensMapperresultNewIni ************************************************
1690 **
1691 ** Constructor for an Ensembl Mapper Result with initial values.
1692 **
1693 ** @param [u] type [EnsEMapperresultType] Type
1694 ** @param [r] oid [ajuint] Ensembl Object identifier
1695 ** @param [r] crdstart [ajint] Start
1696 ** @param [r] crdend [ajint] End
1697 ** @param [r] crdstrand [ajint] Strand
1698 ** @param [u] cs [EnsPCoordsystem] Ensembl Coordinate System
1699 ** @param [r] gapstart [ajint] Gap start
1700 ** @param [r] gapend [ajint] Gap end
1701 ** @param [r] rank [ajuint] Rank
1702 **
1703 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1704 **
1705 ** @release 6.4.0
1706 ** @@
1707 ******************************************************************************/
1708 
ensMapperresultNewIni(EnsEMapperresultType type,ajuint oid,ajint crdstart,ajint crdend,ajint crdstrand,EnsPCoordsystem cs,ajint gapstart,ajint gapend,ajuint rank)1709 EnsPMapperresult ensMapperresultNewIni(EnsEMapperresultType type,
1710                                        ajuint oid,
1711                                        ajint crdstart,
1712                                        ajint crdend,
1713                                        ajint crdstrand,
1714                                        EnsPCoordsystem cs,
1715                                        ajint gapstart,
1716                                        ajint gapend,
1717                                        ajuint rank)
1718 {
1719     EnsPMapperresult mr = NULL;
1720 
1721     if (!type)
1722         return NULL;
1723 
1724     if ((type == ensEMapperresultTypeCoordinate) ||
1725         (type == ensEMapperresultTypeInDel))
1726     {
1727         if (!oid)
1728             return NULL;
1729 
1730         if (!cs)
1731             return NULL;
1732     }
1733 
1734     AJNEW0(mr);
1735 
1736     mr->Type             = type;
1737     mr->Objectidentifier = oid;
1738     mr->CoordinateStart  = crdstart;
1739     mr->CoordinateEnd    = crdend;
1740     mr->CoordinateStrand = crdstrand;
1741     mr->Coordsystem      = ensCoordsystemNewRef(cs);
1742     mr->GapStart         = gapstart;
1743     mr->GapEnd           = gapend;
1744     mr->Rank             = rank;
1745     mr->Use              = 1U;
1746 
1747     return mr;
1748 }
1749 
1750 
1751 
1752 
1753 /* @func ensMapperresultNewRef ************************************************
1754 **
1755 ** Ensembl Object referencing function, which returns a pointer to the
1756 ** Ensembl Object passed in and increases its reference count.
1757 **
1758 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
1759 **
1760 ** @return [EnsPMapperresult] Ensembl Mapper Result or NULL
1761 **
1762 ** @release 6.2.0
1763 ** @@
1764 ******************************************************************************/
1765 
ensMapperresultNewRef(EnsPMapperresult mr)1766 EnsPMapperresult ensMapperresultNewRef(EnsPMapperresult mr)
1767 {
1768     if (!mr)
1769         return NULL;
1770 
1771     mr->Use++;
1772 
1773     return mr;
1774 }
1775 
1776 
1777 
1778 
1779 /* @section destructors *******************************************************
1780 **
1781 ** Destruction destroys all internal data structures and frees the memory
1782 ** allocated for an Ensembl Mapper Result object.
1783 **
1784 ** @fdata [EnsPMapperresult]
1785 **
1786 ** @nam3rule Del Destroy (free) an Ensembl Mapper Result
1787 **
1788 ** @argrule * Pmr [EnsPMapperresult*] Ensembl Mapper Result address
1789 **
1790 ** @valrule * [void]
1791 **
1792 ** @fcategory delete
1793 ******************************************************************************/
1794 
1795 
1796 
1797 
1798 /* @func ensMapperresultDel ***************************************************
1799 **
1800 ** Default destructor for an Ensembl Mapper Result.
1801 **
1802 ** @param [d] Pmr [EnsPMapperresult*] Ensembl Mapper Result address
1803 **
1804 ** @return [void]
1805 **
1806 ** @release 6.2.0
1807 ** @@
1808 ******************************************************************************/
1809 
ensMapperresultDel(EnsPMapperresult * Pmr)1810 void ensMapperresultDel(EnsPMapperresult *Pmr)
1811 {
1812     EnsPMapperresult pthis = NULL;
1813 
1814     if (!Pmr)
1815         return;
1816 
1817 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
1818     if (ajDebugTest("ensMapperresultDel"))
1819     {
1820         ajDebug("ensMapperresultDel\n"
1821                 "  *Pmr %p\n",
1822                 *Pmr);
1823 
1824         ensMapperresultTrace(*Pmr, 1);
1825     }
1826 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
1827 
1828     if (!(pthis = *Pmr) || --pthis->Use)
1829     {
1830         *Pmr = NULL;
1831 
1832         return;
1833     }
1834 
1835     ensCoordsystemDel(&pthis->Coordsystem);
1836 
1837     ajMemFree((void **) Pmr);
1838 
1839     return;
1840 }
1841 
1842 
1843 
1844 
1845 /* @section member retrieval **************************************************
1846 **
1847 ** Functions for returning members of an Ensembl Mapper Result object.
1848 **
1849 ** @fdata [EnsPMapperresult]
1850 **
1851 ** @nam3rule Get Return Ensembl Mapper Result attribute(s)
1852 ** @nam4rule Coordinate Return coordinate members
1853 ** @nam5rule End Return the coordinate end
1854 ** @nam5rule Start Return the coordinate start
1855 ** @nam5rule Strand Return the coordinate strand
1856 ** @nam4rule Coordsystem Return the Ensembl Coordinate System
1857 ** @nam4rule Gap Return gap members
1858 ** @nam5rule End Return the gap end
1859 ** @nam5rule Start Return the gap start
1860 ** @nam4rule Objectidentifier Return the Ensembl Object identifier
1861 ** @nam4rule Rank Return the rank
1862 ** @nam4rule Type Return the type
1863 **
1864 ** @argrule * mr [const EnsPMapperresult] Ensembl Mapper Result
1865 **
1866 ** @valrule Coordsystem [EnsPCoordsystem] Ensembl Coordinate System or NULL
1867 ** @valrule CoordinateEnd [ajint] End or 0
1868 ** @valrule CoordinateStart [ajint] Coordinate start or 0
1869 ** @valrule CoordinateStrand [ajint] Coordinate strand or 0
1870 ** @valrule GapEnd [ajint] Gap end or 0
1871 ** @valrule GapStart [ajint] Gap start or 0
1872 ** @valrule Objectidentifier [ajuint] Ensembl Object identifier or 0U
1873 ** @valrule Rank [ajuint] Rank or 0U
1874 ** @valrule Type [EnsEMapperresultType] Type or ensEMapperresultTypeNULL
1875 **
1876 ** @fcategory use
1877 ******************************************************************************/
1878 
1879 
1880 
1881 
1882 /* @func ensMapperresultGetCoordinateEnd **************************************
1883 **
1884 ** Get the coordinate end member of an Ensembl Mapper Result.
1885 **
1886 ** @cc Bio::EnsEMBL::Mapper::Coordinate::end
1887 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1888 **
1889 ** @return [ajint] Coordinate end or 0
1890 **
1891 ** @release 6.4.0
1892 ** @@
1893 ******************************************************************************/
1894 
ensMapperresultGetCoordinateEnd(const EnsPMapperresult mr)1895 ajint ensMapperresultGetCoordinateEnd(const EnsPMapperresult mr)
1896 {
1897     return (mr) ? mr->CoordinateEnd : 0;
1898 }
1899 
1900 
1901 
1902 
1903 /* @func ensMapperresultGetCoordinateStart ************************************
1904 **
1905 ** Get the coordinate start member of an Ensembl Mapper Result.
1906 **
1907 ** @cc Bio::EnsEMBL::Mapper::Coordinate::start
1908 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1909 **
1910 ** @return [ajint] Coordinate start or 0
1911 **
1912 ** @release 6.4.0
1913 ** @@
1914 ******************************************************************************/
1915 
ensMapperresultGetCoordinateStart(const EnsPMapperresult mr)1916 ajint ensMapperresultGetCoordinateStart(const EnsPMapperresult mr)
1917 {
1918     return (mr) ? mr->CoordinateStart : 0;
1919 }
1920 
1921 
1922 
1923 
1924 /* @func ensMapperresultGetCoordinateStrand ***********************************
1925 **
1926 ** Get the coordinate strand member of an Ensembl Mapper Result.
1927 **
1928 ** @cc Bio::EnsEMBL::Mapper::Coordinate::strand
1929 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1930 **
1931 ** @return [ajint] Coordinate strand or 0
1932 **
1933 ** @release 6.4.0
1934 ** @@
1935 ******************************************************************************/
1936 
ensMapperresultGetCoordinateStrand(const EnsPMapperresult mr)1937 ajint ensMapperresultGetCoordinateStrand(const EnsPMapperresult mr)
1938 {
1939     return (mr) ? mr->CoordinateStrand : 0;
1940 }
1941 
1942 
1943 
1944 
1945 /* @func ensMapperresultGetCoordsystem ****************************************
1946 **
1947 ** Get the Ensembl Coordinate System member of an Ensembl Mapper Result.
1948 **
1949 ** @cc Bio::EnsEMBL::Mapper::Coordinate::coord_system
1950 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1951 **
1952 ** @return [EnsPCoordsystem] Ensembl Coordinate System or NULL
1953 **
1954 ** @release 6.2.0
1955 ** @@
1956 ******************************************************************************/
1957 
ensMapperresultGetCoordsystem(const EnsPMapperresult mr)1958 EnsPCoordsystem ensMapperresultGetCoordsystem(const EnsPMapperresult mr)
1959 {
1960     return (mr) ? mr->Coordsystem : NULL;
1961 }
1962 
1963 
1964 
1965 
1966 /* @func ensMapperresultGetGapEnd *********************************************
1967 **
1968 ** Get the gap end member of an Ensembl Mapper Result.
1969 **
1970 ** @cc Bio::EnsEMBL::Mapper::Gap::end
1971 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1972 **
1973 ** @return [ajint] Gap end or 0
1974 **
1975 ** @release 6.2.0
1976 ** @@
1977 ******************************************************************************/
1978 
ensMapperresultGetGapEnd(const EnsPMapperresult mr)1979 ajint ensMapperresultGetGapEnd(const EnsPMapperresult mr)
1980 {
1981     return (mr) ? mr->GapEnd : 0;
1982 }
1983 
1984 
1985 
1986 
1987 /* @func ensMapperresultGetGapStart *******************************************
1988 **
1989 ** Get the gap start member of an Ensembl Mapper Result.
1990 **
1991 ** @cc Bio::EnsEMBL::Mapper::Gap::start
1992 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
1993 **
1994 ** @return [ajint] Gap start or 0
1995 **
1996 ** @release 6.2.0
1997 ** @@
1998 ******************************************************************************/
1999 
ensMapperresultGetGapStart(const EnsPMapperresult mr)2000 ajint ensMapperresultGetGapStart(const EnsPMapperresult mr)
2001 {
2002     return (mr) ? mr->GapStart : 0;
2003 }
2004 
2005 
2006 
2007 
2008 /* @func ensMapperresultGetObjectidentifier ***********************************
2009 **
2010 ** Get the Ensembl Object identifier member of an Ensembl Mapper Result.
2011 **
2012 ** @cc Bio::EnsEMBL::Mapper::Coordinate::id
2013 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2014 **
2015 ** @return [ajuint] Ensembl Object identifier or 0U
2016 **
2017 ** @release 6.4.0
2018 ** @@
2019 ******************************************************************************/
2020 
ensMapperresultGetObjectidentifier(const EnsPMapperresult mr)2021 ajuint ensMapperresultGetObjectidentifier(const EnsPMapperresult mr)
2022 {
2023     return (mr) ? mr->Objectidentifier : 0U;
2024 }
2025 
2026 
2027 
2028 
2029 /* @func ensMapperresultGetRank ***********************************************
2030 **
2031 ** Get the rank member of an Ensembl Mapper Result.
2032 **
2033 ** @cc Bio::EnsEMBL::Mapper::Coordinate::rank
2034 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2035 **
2036 ** @return [ajuint] Rank or 0U
2037 **
2038 ** @release 6.3.0
2039 ** @@
2040 ******************************************************************************/
2041 
ensMapperresultGetRank(const EnsPMapperresult mr)2042 ajuint ensMapperresultGetRank(const EnsPMapperresult mr)
2043 {
2044     return (mr) ? mr->Rank : 0U;
2045 }
2046 
2047 
2048 
2049 
2050 /* @func ensMapperresultGetType ***********************************************
2051 **
2052 ** Get the type member of an Ensembl Mapper Result.
2053 **
2054 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2055 **
2056 ** @return [EnsEMapperresultType] Type or ensEMapperresultTypeNULL
2057 **
2058 ** @release 6.2.0
2059 ** @@
2060 ******************************************************************************/
2061 
ensMapperresultGetType(const EnsPMapperresult mr)2062 EnsEMapperresultType ensMapperresultGetType(const EnsPMapperresult mr)
2063 {
2064     return (mr) ? mr->Type : ensEMapperresultTypeNULL;
2065 }
2066 
2067 
2068 
2069 
2070 /* @section member assignment *************************************************
2071 **
2072 ** Functions for assigning members of an Ensembl Mapper Result object.
2073 **
2074 ** @fdata [EnsPMapperresult]
2075 **
2076 ** @nam3rule Set Set one member of an Ensembl Mapper Result
2077 ** @nam4rule Coordinate Set a coordinate
2078 ** @nam4rule Gap Set a gap
2079 ** @nam5rule End Set the end
2080 ** @nam5rule Start Set the start
2081 ** @nam5rule Strand Set the strand
2082 ** @nam4rule Coordsystem Set the Ensembl Coordinate System
2083 ** @nam4rule Objectidentifier Set the Ensembl Object identifier
2084 ** @nam4rule Rank Set the rank
2085 ** @nam4rule Type Set the type
2086 **
2087 ** @argrule * mr [EnsPMapperresult] Ensembl Mapper Result object
2088 ** @argrule CoordinateEnd crdend [ajint] End
2089 ** @argrule CoordinateStart crdstart [ajint] Start
2090 ** @argrule CoordinateStrand crdstrand [ajint] Strand
2091 ** @argrule Coordsystem cs [EnsPCoordsystem] Ensembl Coordinate System
2092 ** @argrule GapEnd gapend [ajint] End
2093 ** @argrule GapStart gapstart [ajint] Start
2094 ** @argrule Objectidentifier oid [ajuint] Ensembl Object identifier
2095 ** @argrule Rank rank [ajuint] Rank
2096 ** @argrule Type mrt [EnsEMapperresultType]
2097 ** Ensembl Mapper Result Type enumeration
2098 **
2099 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
2100 **
2101 ** @fcategory modify
2102 ******************************************************************************/
2103 
2104 
2105 
2106 
2107 /* @func ensMapperresultSetCoordinateEnd **************************************
2108 **
2109 ** Set the coordinate end member of an Ensembl Mapper Result.
2110 **
2111 ** @cc Bio::EnsEMBL::Mapper::Coordinate::end
2112 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2113 ** @param [r] crdend [ajint] End
2114 **
2115 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2116 **
2117 ** @release 6.4.0
2118 ** @@
2119 ******************************************************************************/
2120 
ensMapperresultSetCoordinateEnd(EnsPMapperresult mr,ajint crdend)2121 AjBool ensMapperresultSetCoordinateEnd(EnsPMapperresult mr,
2122                                        ajint crdend)
2123 {
2124     if (!mr)
2125         return ajFalse;
2126 
2127     mr->CoordinateEnd = crdend;
2128 
2129     return ajTrue;
2130 }
2131 
2132 
2133 
2134 
2135 /* @func ensMapperresultSetCoordinateStart ************************************
2136 **
2137 ** Set the coordinate start member of an Ensembl Mapper Result.
2138 **
2139 ** @cc Bio::EnsEMBL::Mapper::Coordinate::start
2140 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2141 ** @param [r] crdstart [ajint] Start
2142 **
2143 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2144 **
2145 ** @release 6.4.0
2146 ** @@
2147 ******************************************************************************/
2148 
ensMapperresultSetCoordinateStart(EnsPMapperresult mr,ajint crdstart)2149 AjBool ensMapperresultSetCoordinateStart(EnsPMapperresult mr,
2150                                          ajint crdstart)
2151 {
2152     if (!mr)
2153         return ajFalse;
2154 
2155     mr->CoordinateStart = crdstart;
2156 
2157     return ajTrue;
2158 }
2159 
2160 
2161 
2162 
2163 /* @func ensMapperresultSetCoordinateStrand ***********************************
2164 **
2165 ** Set the coordinate strand member of an Ensembl Mapper Result.
2166 **
2167 ** @cc Bio::EnsEMBL::Mapper::Coordinate::strand
2168 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2169 ** @param [r] crdstrand [ajint] Strand
2170 **
2171 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2172 **
2173 ** @release 6.4.0
2174 ** @@
2175 ******************************************************************************/
2176 
ensMapperresultSetCoordinateStrand(EnsPMapperresult mr,ajint crdstrand)2177 AjBool ensMapperresultSetCoordinateStrand(EnsPMapperresult mr,
2178                                           ajint crdstrand)
2179 {
2180     if (!mr)
2181         return ajFalse;
2182 
2183     mr->CoordinateStrand = crdstrand;
2184 
2185     return ajTrue;
2186 }
2187 
2188 
2189 
2190 
2191 /* @func ensMapperresultSetCoordsystem ****************************************
2192 **
2193 ** Set the Ensembl Coordinate System member of an Ensembl Mapper Result.
2194 **
2195 ** @cc Bio::EnsEMBL::Mapper::Coordinate::coord_system
2196 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2197 ** @param [u] cs [EnsPCoordsystem] Ensembl Coordinate System
2198 **
2199 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2200 **
2201 ** @release 6.4.0
2202 ** @@
2203 ******************************************************************************/
2204 
ensMapperresultSetCoordsystem(EnsPMapperresult mr,EnsPCoordsystem cs)2205 AjBool ensMapperresultSetCoordsystem(EnsPMapperresult mr,
2206                                      EnsPCoordsystem cs)
2207 {
2208     if (!mr)
2209         return ajFalse;
2210 
2211     ensCoordsystemDel(&mr->Coordsystem);
2212 
2213     mr->Coordsystem = ensCoordsystemNewRef(cs);
2214 
2215     return ajTrue;
2216 }
2217 
2218 
2219 
2220 
2221 /* @func ensMapperresultSetGapEnd *********************************************
2222 **
2223 ** Set the gap end member of an Ensembl Mapper Result.
2224 **
2225 ** @cc Bio::EnsEMBL::Mapper::Gap::end
2226 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2227 ** @param [r] gapend [ajint] End
2228 **
2229 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2230 **
2231 ** @release 6.4.0
2232 ** @@
2233 ******************************************************************************/
2234 
ensMapperresultSetGapEnd(EnsPMapperresult mr,ajint gapend)2235 AjBool ensMapperresultSetGapEnd(EnsPMapperresult mr,
2236                                 ajint gapend)
2237 {
2238     if (!mr)
2239         return ajFalse;
2240 
2241     mr->GapEnd = gapend;
2242 
2243     return ajTrue;
2244 }
2245 
2246 
2247 
2248 
2249 /* @func ensMapperresultSetGapStart *******************************************
2250 **
2251 ** Set the gap start member of an Ensembl Mapper Result.
2252 **
2253 ** @cc Bio::EnsEMBL::Mapper::Gap::start
2254 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2255 ** @param [r] gapstart [ajint] Start
2256 **
2257 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2258 **
2259 ** @release 6.4.0
2260 ** @@
2261 ******************************************************************************/
2262 
ensMapperresultSetGapStart(EnsPMapperresult mr,ajint gapstart)2263 AjBool ensMapperresultSetGapStart(EnsPMapperresult mr,
2264                                   ajint gapstart)
2265 {
2266     if (!mr)
2267         return ajFalse;
2268 
2269     mr->GapStart = gapstart;
2270 
2271     return ajTrue;
2272 }
2273 
2274 
2275 
2276 
2277 /* @func ensMapperresultSetObjectidentifier ***********************************
2278 **
2279 ** Set the Ensembl Object identifier member of an Ensembl Mapper Result.
2280 **
2281 ** @cc Bio::EnsEMBL::Mapper::Coordinate::id
2282 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2283 ** @param [r] oid [ajuint] Ensembl Object identifier
2284 **
2285 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2286 **
2287 ** @release 6.4.0
2288 ** @@
2289 ******************************************************************************/
2290 
ensMapperresultSetObjectidentifier(EnsPMapperresult mr,ajuint oid)2291 AjBool ensMapperresultSetObjectidentifier(EnsPMapperresult mr,
2292                                           ajuint oid)
2293 {
2294     if (!mr)
2295         return ajFalse;
2296 
2297     mr->Objectidentifier = oid;
2298 
2299     return ajTrue;
2300 }
2301 
2302 
2303 
2304 
2305 /* @func ensMapperresultSetRank ***********************************************
2306 **
2307 ** Set the rank member of an Ensembl Mapper Result.
2308 **
2309 ** @cc Bio::EnsEMBL::Mapper::Coordinate::rank
2310 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2311 ** @param [r] rank [ajuint] Rank
2312 **
2313 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2314 **
2315 ** @release 6.4.0
2316 ** @@
2317 ******************************************************************************/
2318 
ensMapperresultSetRank(EnsPMapperresult mr,ajuint rank)2319 AjBool ensMapperresultSetRank(EnsPMapperresult mr,
2320                               ajuint rank)
2321 {
2322     if (!mr)
2323         return ajFalse;
2324 
2325     mr->Rank = rank;
2326 
2327     return ajTrue;
2328 }
2329 
2330 
2331 
2332 
2333 /* @func ensMapperresultSetType ***********************************************
2334 **
2335 ** Set the type member of an Ensembl Mapper Result.
2336 **
2337 ** @param [u] mr [EnsPMapperresult] Ensembl Mapper Result
2338 ** @param [u] mrt [EnsEMapperresultType]
2339 ** Ensembl Mapper Result Type enumeration
2340 **
2341 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2342 **
2343 ** @release 6.4.0
2344 ** @@
2345 ******************************************************************************/
2346 
ensMapperresultSetType(EnsPMapperresult mr,EnsEMapperresultType mrt)2347 AjBool ensMapperresultSetType(EnsPMapperresult mr,
2348                               EnsEMapperresultType mrt)
2349 {
2350     if (!mr)
2351         return ajFalse;
2352 
2353     mr->Type = mrt;
2354 
2355     return ajTrue;
2356 }
2357 
2358 
2359 
2360 
2361 /* @section debugging *********************************************************
2362 **
2363 ** Functions for reporting of an Ensembl Mapper Result object.
2364 **
2365 ** @fdata [EnsPMapperresult]
2366 **
2367 ** @nam3rule Trace Report Ensembl Mapper Result members to debug file
2368 **
2369 ** @argrule Trace mr [const EnsPMapperresult] Ensembl Mapper Result
2370 ** @argrule Trace level [ajuint] Indentation level
2371 **
2372 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
2373 **
2374 ** @fcategory misc
2375 ******************************************************************************/
2376 
2377 
2378 
2379 
2380 /* @func ensMapperresultTrace *************************************************
2381 **
2382 ** Trace an Ensembl Mapper Result.
2383 **
2384 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2385 ** @param [r] level [ajuint] Indentation level
2386 **
2387 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2388 **
2389 ** @release 6.2.0
2390 ** @@
2391 ******************************************************************************/
2392 
ensMapperresultTrace(const EnsPMapperresult mr,ajuint level)2393 AjBool ensMapperresultTrace(const EnsPMapperresult mr, ajuint level)
2394 {
2395     AjPStr indent = NULL;
2396 
2397     if (!mr)
2398         return ajFalse;
2399 
2400     indent = ajStrNew();
2401 
2402     ajStrAppendCountK(&indent, ' ', level * 2);
2403 
2404     ajDebug("%SensMapperresultTrace %p\n"
2405             "%S  Type %d\n"
2406             "%S  Objectidentifier %u\n"
2407             "%S  CoordinateStart %d\n"
2408             "%S  CoordinateEnd %d\n"
2409             "%S  CoordinateStrand %d\n"
2410             "%S  Coordsystem %p\n"
2411             "%S  GapStart %d\n"
2412             "%S  GapEnd %d\n"
2413             "%S  Rank %u\n"
2414             "%S  Use %u\n",
2415             indent, mr,
2416             indent, mr->Type,
2417             indent, mr->Objectidentifier,
2418             indent, mr->CoordinateStart,
2419             indent, mr->CoordinateEnd,
2420             indent, mr->CoordinateStrand,
2421             indent, mr->Coordsystem,
2422             indent, mr->GapStart,
2423             indent, mr->GapEnd,
2424             indent, mr->Rank,
2425             indent, mr->Use);
2426 
2427     ensCoordsystemTrace(mr->Coordsystem, level + 1);
2428 
2429     ajStrDel(&indent);
2430 
2431     return ajTrue;
2432 }
2433 
2434 
2435 
2436 
2437 /* @section calculate *********************************************************
2438 **
2439 ** Functions for calculating information from an Ensembl Mapper Result object.
2440 **
2441 ** @fdata [EnsPMapperresult]
2442 **
2443 ** @nam3rule Calculate Calculate Ensembl Mapper Result information
2444 ** @nam4rule Length Calculate the length
2445 ** @nam5rule Coordinate Ensembl Mapper Result Type
2446 ** ensEMapperresultTypeCoordinate
2447 ** @nam5rule Gap Ensembl Mapper Result Type ensEMapperresultTypeGap
2448 ** @nam5rule Result Ensembl Mapper Result Type
2449 ** @nam4rule Memsize Calculate the memory size in bytes
2450 **
2451 ** @argrule * mr [const EnsPMapperresult] Ensembl Mapper Result
2452 **
2453 ** @valrule Length [ajuint] Length or 0U
2454 ** @valrule Memsize [size_t] Memory size in bytes or 0
2455 **
2456 ** @fcategory misc
2457 ******************************************************************************/
2458 
2459 
2460 
2461 
2462 /* @func ensMapperresultCalculateLengthCoordinate *****************************
2463 **
2464 ** Calculate the length of an Ensembl Mapper Result of
2465 ** Ensembl Mapper Result Type ensEMapperresultTypeCoordinate.
2466 **
2467 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2468 **
2469 ** @return [ajuint] Coordinate length or 0U
2470 **
2471 ** @release 6.4.0
2472 ** @@
2473 ******************************************************************************/
2474 
ensMapperresultCalculateLengthCoordinate(const EnsPMapperresult mr)2475 ajuint ensMapperresultCalculateLengthCoordinate(const EnsPMapperresult mr)
2476 {
2477     if (!mr)
2478         return 0U;
2479 
2480     return mr->CoordinateEnd - mr->CoordinateStart + 1U;
2481 }
2482 
2483 
2484 
2485 
2486 /* @func ensMapperresultCalculateLengthGap ************************************
2487 **
2488 ** Calculate the length gap of an Ensembl Mapper Result of
2489 ** Ensembl Mapper Result Type ensEMapperresultTypeGap.
2490 **
2491 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2492 **
2493 ** @return [ajuint] Gap length or 0U
2494 **
2495 ** @release 6.4.0
2496 ** @@
2497 ******************************************************************************/
2498 
ensMapperresultCalculateLengthGap(const EnsPMapperresult mr)2499 ajuint ensMapperresultCalculateLengthGap(const EnsPMapperresult mr)
2500 {
2501     if (!mr)
2502         return 0U;
2503 
2504     return mr->GapEnd - mr->GapStart + 1U;
2505 }
2506 
2507 
2508 
2509 
2510 /* @func ensMapperresultCalculateLengthResult *********************************
2511 **
2512 ** Get the length of an Ensembl Mapper Result.
2513 ** This is the coordinate length for Mapper Results of type
2514 ** ensEMapperresultTypeCoordinate and ensEMapperresultTypeInDel and the
2515 ** gap length for Mapper Resuls of type ensEMapperresultTypeGap.
2516 **
2517 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2518 **
2519 ** @return [ajuint] Ensembl Mapper Result length or 0U
2520 **
2521 ** @release 6.4.0
2522 ** @@
2523 ******************************************************************************/
2524 
ensMapperresultCalculateLengthResult(const EnsPMapperresult mr)2525 ajuint ensMapperresultCalculateLengthResult(const EnsPMapperresult mr)
2526 {
2527     if (!mr)
2528         return 0U;
2529 
2530     switch (mr->Type)
2531     {
2532         case ensEMapperresultTypeCoordinate:
2533             return ensMapperresultCalculateLengthCoordinate(mr);
2534         case ensEMapperresultTypeGap:
2535             return ensMapperresultCalculateLengthGap(mr);
2536         case ensEMapperresultTypeInDel:
2537             return ensMapperresultCalculateLengthCoordinate(mr);
2538         default:
2539             ajWarn("ensMapperresultCalculateLengthResult got unexpected "
2540                    "Ensembl Mapper Result type %d.\n", mr->Type);
2541     }
2542 
2543     return 0U;
2544 }
2545 
2546 
2547 
2548 
2549 /* @func ensMapperresultCalculateMemsize **************************************
2550 **
2551 ** Calculate the memory size in bytes of an Ensembl Mapper Result.
2552 **
2553 ** @param [r] mr [const EnsPMapperresult] Ensembl Mapper Result
2554 **
2555 ** @return [size_t] Memory size in bytes or 0
2556 **
2557 ** @release 6.4.0
2558 ** @@
2559 ******************************************************************************/
2560 
ensMapperresultCalculateMemsize(const EnsPMapperresult mr)2561 size_t ensMapperresultCalculateMemsize(const EnsPMapperresult mr)
2562 {
2563     size_t size = 0;
2564 
2565     if (!mr)
2566         return 0;
2567 
2568     size += sizeof (EnsOMapperresult);
2569 
2570     return size;
2571 }
2572 
2573 
2574 
2575 
2576 /* @datasection [EnsPMapperrange] Ensembl Mapper Range ************************
2577 **
2578 ** @nam2rule Mapperrange Functions for manipulating
2579 ** Ensembl Mapper Range objects
2580 **
2581 ******************************************************************************/
2582 
2583 
2584 
2585 
2586 /* @section constructors ******************************************************
2587 **
2588 ** All constructors return a new Ensembl Mapper Range by pointer.
2589 ** It is the responsibility of the user to first destroy any previous
2590 ** Mapper Range. The target pointer does not need to be initialised to
2591 ** NULL, but it is good programming practice to do so anyway.
2592 **
2593 ** @fdata [EnsPMapperrange]
2594 **
2595 ** @nam3rule New Constructor
2596 ** @nam4rule Cpy Constructor with existing object
2597 ** @nam4rule Ini Constructor with initial values
2598 ** @nam4rule Ref Constructor by incrementing the reference counter
2599 **
2600 ** @argrule Cpy mr [const EnsPMapperrange] Ensembl Mapper Range
2601 ** @argrule Ini start [ajint] Start
2602 ** @argrule Ini end [ajint] End
2603 ** @argrule Ref mr [EnsPMapperrange] Ensembl Mapper Range
2604 **
2605 ** @valrule * [EnsPMapperrange] Ensembl Mapper Range or NULL
2606 **
2607 ** @fcategory new
2608 ******************************************************************************/
2609 
2610 
2611 
2612 
2613 /* @func ensMapperrangeNewCpy *************************************************
2614 **
2615 ** Object-based constructor function, which returns an independent object.
2616 **
2617 ** @param [r] mr [const EnsPMapperrange] Ensembl Mapper Range
2618 **
2619 ** @return [EnsPMapperrange] Ensembl Mapper Range or NULL
2620 **
2621 ** @release 6.4.0
2622 ** @@
2623 ******************************************************************************/
2624 
ensMapperrangeNewCpy(const EnsPMapperrange mr)2625 EnsPMapperrange ensMapperrangeNewCpy(const EnsPMapperrange mr)
2626 {
2627     EnsPMapperrange pthis = NULL;
2628 
2629     if (!mr)
2630         return NULL;
2631 
2632     AJNEW0(pthis);
2633 
2634     pthis->Start = mr->Start;
2635     pthis->End   = mr->End;
2636     pthis->Use   = 1U;
2637 
2638     return pthis;
2639 }
2640 
2641 
2642 
2643 
2644 /* @func ensMapperrangeNewIni *************************************************
2645 **
2646 ** Constructor for an Ensembl Mapper Range with initial values.
2647 **
2648 ** @param [r] start [ajint] Start
2649 ** @param [r] end [ajint] End
2650 **
2651 ** @return [EnsPMapperrange] Ensembl Mapper Range or NULL
2652 **
2653 ** @release 6.4.0
2654 ** @@
2655 ******************************************************************************/
2656 
ensMapperrangeNewIni(ajint start,ajint end)2657 EnsPMapperrange ensMapperrangeNewIni(ajint start, ajint end)
2658 {
2659     EnsPMapperrange mr = NULL;
2660 
2661     AJNEW0(mr);
2662 
2663     mr->Start = start;
2664     mr->End   = end;
2665     mr->Use   = 1U;
2666 
2667     return mr;
2668 }
2669 
2670 
2671 
2672 
2673 /* @func ensMapperrangeNewRef *************************************************
2674 **
2675 ** Ensembl Object referencing function, which returns a pointer to the
2676 ** Ensembl Object passed in and increases its reference count.
2677 **
2678 ** @param [u] mr [EnsPMapperrange] Ensembl Mapper Range
2679 **
2680 ** @return [EnsPMapperrange] Ensembl Mapper Range or NULL
2681 **
2682 ** @release 6.2.0
2683 ** @@
2684 ******************************************************************************/
2685 
ensMapperrangeNewRef(EnsPMapperrange mr)2686 EnsPMapperrange ensMapperrangeNewRef(EnsPMapperrange mr)
2687 {
2688     if (!mr)
2689         return NULL;
2690 
2691     mr->Use++;
2692 
2693     return mr;
2694 }
2695 
2696 
2697 
2698 
2699 /* @section destructors *******************************************************
2700 **
2701 ** Destruction destroys all internal data structures and frees the memory
2702 ** allocated for an Ensembl Mapper Range object.
2703 **
2704 ** @fdata [EnsPMapperrange]
2705 **
2706 ** @nam3rule Del Destroy (free) an Ensembl Mapper Range
2707 **
2708 ** @argrule * Pmr [EnsPMapperrange*] Ensembl Mapper Range address
2709 **
2710 ** @valrule * [void]
2711 **
2712 ** @fcategory delete
2713 ******************************************************************************/
2714 
2715 
2716 
2717 
2718 /* @func ensMapperrangeDel ****************************************************
2719 **
2720 ** Default destructor for an Ensembl Mapper Range.
2721 **
2722 ** @param [d] Pmr [EnsPMapperrange*] Ensembl Mapper Range address
2723 **
2724 ** @return [void]
2725 **
2726 ** @release 6.2.0
2727 ** @@
2728 ******************************************************************************/
2729 
ensMapperrangeDel(EnsPMapperrange * Pmr)2730 void ensMapperrangeDel(EnsPMapperrange *Pmr)
2731 {
2732     EnsPMapperrange pthis = NULL;
2733 
2734     if (!Pmr)
2735         return;
2736 
2737 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
2738     if (ajDebugTest("ensMapperrangeDel"))
2739     {
2740         ajDebug("ensMapperrangeDel\n"
2741                 "  *Pmr %p\n",
2742                 *Pmr);
2743 
2744         ensMapperrangeTrace(*Pmr, 1);
2745     }
2746 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
2747 
2748     if (!(pthis = *Pmr) || --pthis->Use)
2749     {
2750         *Pmr = NULL;
2751 
2752         return;
2753     }
2754 
2755     ajMemFree((void **) Pmr);
2756 
2757     return;
2758 }
2759 
2760 
2761 
2762 
2763 /* @section member retrieval **************************************************
2764 **
2765 ** Functions for returning members of an Ensembl Mapper Range object.
2766 **
2767 ** @fdata [EnsPMapperrange]
2768 **
2769 ** @nam3rule Get Return Ensembl Mapper Range attribute(s)
2770 ** @nam4rule GetEnd Return the end
2771 ** @nam4rule GetStart Return the start
2772 **
2773 ** @argrule * mr [const EnsPMapperrange] Ensembl Mapper Range
2774 **
2775 ** @valrule End [ajint] End or 0
2776 ** @valrule Start [ajint] Start or 0
2777 **
2778 ** @fcategory use
2779 ******************************************************************************/
2780 
2781 
2782 
2783 
2784 /* @func ensMapperrangeGetEnd *************************************************
2785 **
2786 ** Get the end member of an Ensembl Mapper Range.
2787 **
2788 ** @param [r] mr [const EnsPMapperrange] Ensembl Mapper Range
2789 **
2790 ** @return [ajint] End or 0
2791 **
2792 ** @release 6.2.0
2793 ** @@
2794 ******************************************************************************/
2795 
ensMapperrangeGetEnd(const EnsPMapperrange mr)2796 ajint ensMapperrangeGetEnd(const EnsPMapperrange mr)
2797 {
2798     return (mr) ? mr->End : 0;
2799 }
2800 
2801 
2802 
2803 
2804 /* @func ensMapperrangeGetStart ***********************************************
2805 **
2806 ** Get the start member of an Ensembl Mapper Range.
2807 **
2808 ** @param [r] mr [const EnsPMapperrange] Ensembl Mapper Range
2809 **
2810 ** @return [ajint] Start or 0
2811 **
2812 ** @release 6.2.0
2813 ** @@
2814 ******************************************************************************/
2815 
ensMapperrangeGetStart(const EnsPMapperrange mr)2816 ajint ensMapperrangeGetStart(const EnsPMapperrange mr)
2817 {
2818     return (mr) ? mr->Start : 0;
2819 }
2820 
2821 
2822 
2823 
2824 /* @section debugging *********************************************************
2825 **
2826 ** Functions for reporting of an Ensembl Mapper Range object.
2827 **
2828 ** @fdata [EnsPMapperrange]
2829 **
2830 ** @nam3rule Trace Report Ensembl Mapper Range members to debug file
2831 **
2832 ** @argrule Trace mr [const EnsPMapperrange] Ensembl Mapper Range
2833 ** @argrule Trace level [ajuint] Indentation level
2834 **
2835 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
2836 **
2837 ** @fcategory misc
2838 ******************************************************************************/
2839 
2840 
2841 
2842 
2843 /* @func ensMapperrangeTrace **************************************************
2844 **
2845 ** Trace an Ensembl Mapper Range.
2846 **
2847 ** @param [r] mr [const EnsPMapperrange] Ensembl Mapper Range
2848 ** @param [r] level [ajuint] Indentation level
2849 **
2850 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2851 **
2852 ** @release 6.4.0
2853 ** @@
2854 ******************************************************************************/
2855 
ensMapperrangeTrace(const EnsPMapperrange mr,ajuint level)2856 AjBool ensMapperrangeTrace(const EnsPMapperrange mr, ajuint level)
2857 {
2858     AjPStr indent = NULL;
2859 
2860     if (!mr)
2861         return ajFalse;
2862 
2863     indent = ajStrNew();
2864 
2865     ajStrAppendCountK(&indent, ' ', level * 2);
2866 
2867     ajDebug("%SensMapperrangeTrace %p\n"
2868             "%S  Start %d\n"
2869             "%S  End %d\n"
2870             "%S  Use %u\n",
2871             indent, mr,
2872             indent, mr->Start,
2873             indent, mr->End,
2874             indent, mr->Use);
2875 
2876     ajStrDel(&indent);
2877 
2878     return ajTrue;
2879 }
2880 
2881 
2882 
2883 
2884 /* @section calculate *********************************************************
2885 **
2886 ** Functions for calculating information from an Ensembl Mapper Range object.
2887 **
2888 ** @fdata [EnsPMapperrange]
2889 **
2890 ** @nam3rule Calculate Calculate Ensembl Mapper Range information
2891 ** @nam4rule Memsize Calculate the memory size in bytes
2892 **
2893 ** @argrule * mr [const EnsPMapperrange] Ensembl Mapper Range
2894 **
2895 ** @valrule Memsize [size_t] Memory size in bytes or 0
2896 **
2897 ** @fcategory misc
2898 ******************************************************************************/
2899 
2900 
2901 
2902 
2903 /* @func ensMapperrangeCalculateMemsize ***************************************
2904 **
2905 ** Calculate the memory size in bytes of an Ensembl Mapper Range.
2906 **
2907 ** @param [r] mr [const EnsPMapperrange] Ensembl Mapper Range
2908 **
2909 ** @return [size_t] Memory size in bytes or 0
2910 **
2911 ** @release 6.4.0
2912 ** @@
2913 ******************************************************************************/
2914 
ensMapperrangeCalculateMemsize(const EnsPMapperrange mr)2915 size_t ensMapperrangeCalculateMemsize(const EnsPMapperrange mr)
2916 {
2917     size_t size = 0;
2918 
2919     if (!mr)
2920         return 0;
2921 
2922     size += sizeof (EnsOMapperrange);
2923 
2924     return size;
2925 }
2926 
2927 
2928 
2929 
2930 /* @datasection [EnsPMapperrangeregistry] Ensembl Mapper Range Registry *******
2931 **
2932 ** @nam2rule Mapperrangeregistry Functions for manipulating
2933 ** Ensembl Mapper Range Registry objects
2934 **
2935 ** @cc Bio::EnsEMBL::Mapper::RangeRegistry
2936 ** @cc CVS Revision: 1.18
2937 ** @cc CVS Tag: branch-ensembl-68
2938 **
2939 ******************************************************************************/
2940 
2941 
2942 
2943 
2944 /* @section constructors ******************************************************
2945 **
2946 ** All constructors return a new Ensembl Mapper Range Registry by pointer.
2947 ** It is the responsibility of the user to first destroy any previous
2948 ** Mapper Range Registry. The target pointer does not need to be initialised to
2949 ** NULL, but it is good programming practice to do so anyway.
2950 **
2951 ** @fdata [EnsPMapperrangeregistry]
2952 **
2953 ** @nam3rule New Constructor
2954 ** @nam4rule Cpy Constructor with existing object
2955 ** @nam4rule Ini Constructor with initial values
2956 ** @nam4rule Ref Constructor by incrementing the reference counter
2957 **
2958 ** @argrule Cpy mrr [const EnsPMapperrangeregistry]
2959 ** Ensembl Mapper Range Registry
2960 ** @argrule Ref mrr [EnsPMapperrangeregistry]
2961 ** Ensembl Mapper Range Registry
2962 **
2963 ** @valrule * [EnsPMapperrangeregistry] Ensembl Mapper Range Registry or NULL
2964 **
2965 ** @fcategory new
2966 ******************************************************************************/
2967 
2968 
2969 
2970 
2971 /* @funcstatic mapperrangeregistryListMapperrangeValdel ***********************
2972 **
2973 ** An ajTableSetDestroyvalue "valdel" function to clear AJAX Table value data.
2974 ** This function removes and deletes Ensembl Mapper Range objects
2975 ** from an AJAX List object, before deleting the AJAX List object.
2976 **
2977 ** @param [d] Pvalue [void**] AJAX List address
2978 ** @see ajTableSetDestroyvalue
2979 **
2980 ** @return [void]
2981 **
2982 ** @release 6.4.0
2983 ** @@
2984 ******************************************************************************/
2985 
mapperrangeregistryListMapperrangeValdel(void ** Pvalue)2986 static void mapperrangeregistryListMapperrangeValdel(void **Pvalue)
2987 {
2988     EnsPMapperrange mr = NULL;
2989 
2990     if (!Pvalue)
2991         return;
2992 
2993     if (!*Pvalue)
2994         return;
2995 
2996     while (ajListPop(*((AjPList *) Pvalue), (void **) &mr))
2997         ensMapperrangeDel(&mr);
2998 
2999     ajListFree((AjPList *) Pvalue);
3000 
3001     return;
3002 }
3003 
3004 
3005 
3006 
3007 /* @func ensMapperrangeregistryNew ********************************************
3008 **
3009 ** Default constructor for an Ensembl Mapper Range Registry.
3010 **
3011 ** @cc Bio::EnsEMBL::Mapper::RangeRegistry::new
3012 ** @return [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3013 **
3014 ** @release 6.2.0
3015 ** @@
3016 ** The Ensembl Mapper Range Registry maintains an internal list of registered
3017 ** regions and is used to quickly ascertain if and what regions of a provided
3018 ** range need registration. It is implemented as a first-level AJAX Table with
3019 ** Ensembl Object identifers as keys and second-level AJAX List objects of
3020 ** Ensembl Mapper Range objects as values.
3021 ******************************************************************************/
3022 
ensMapperrangeregistryNew(void)3023 EnsPMapperrangeregistry ensMapperrangeregistryNew(void)
3024 {
3025     EnsPMapperrangeregistry mrr = NULL;
3026 
3027     if (ajDebugTest("ensMapperrangeregistryNew"))
3028         ajDebug("ensMapperrangeregistryNew\n");
3029 
3030     AJNEW0(mrr);
3031 
3032     mrr->Registry = ajTableuintNew(0U);
3033 
3034     ajTableSetDestroyvalue(
3035         mrr->Registry,
3036         (void (*)(void **)) &mapperrangeregistryListMapperrangeValdel);
3037 
3038     mrr->Use = 1U;
3039 
3040     return mrr;
3041 }
3042 
3043 
3044 
3045 
3046 /* @func ensMapperrangeregistryNewRef *****************************************
3047 **
3048 ** Ensembl Object referencing function, which returns a pointer to the
3049 ** Ensembl Object passed in and increases its reference count.
3050 **
3051 ** @param [u] mrr [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3052 **
3053 ** @return [EnsPMapperrangeregistry] Ensembl Mapper Range Registry or NULL
3054 **
3055 ** @release 6.2.0
3056 ** @@
3057 ******************************************************************************/
3058 
ensMapperrangeregistryNewRef(EnsPMapperrangeregistry mrr)3059 EnsPMapperrangeregistry ensMapperrangeregistryNewRef(
3060     EnsPMapperrangeregistry mrr)
3061 {
3062     if (!mrr)
3063         return NULL;
3064 
3065     mrr->Use++;
3066 
3067     return mrr;
3068 }
3069 
3070 
3071 
3072 
3073 /* @section clear *************************************************************
3074 **
3075 ** Clear internal data structures and frees the
3076 ** memory allocated for Ensembl Mapper Range Registry internals.
3077 **
3078 ** @fdata [EnsPMapperrangeregistry]
3079 **
3080 ** @nam3rule Clear Clear (free) an Ensembl Mapper Range Registry object
3081 **
3082 ** @argrule * mrr [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3083 **
3084 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
3085 **
3086 ** @fcategory delete
3087 ******************************************************************************/
3088 
3089 
3090 
3091 
3092 /* @func ensMapperrangeregistryClear ******************************************
3093 **
3094 ** Clear an Ensembl Mapper Range Registry.
3095 ** This function clears the unsigned integer key data and the AJAX List value
3096 ** data from the first-level AJAX Table, as well as the Ensembl Mapper Range
3097 ** objects from the second-level AJAX List.
3098 **
3099 ** @param [u] mrr [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3100 **
3101 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3102 **
3103 ** @release 6.2.0
3104 ** @@
3105 ******************************************************************************/
3106 
ensMapperrangeregistryClear(EnsPMapperrangeregistry mrr)3107 AjBool ensMapperrangeregistryClear(EnsPMapperrangeregistry mrr)
3108 {
3109     if (ajDebugTest("ensMapperrangeregistryClear"))
3110         ajDebug("ensMapperrangeregistryClear\n"
3111                 "  mrr %p\n",
3112                 mrr);
3113 
3114     if (!mrr)
3115         return ajFalse;
3116 
3117     ajTableClearDelete(mrr->Registry);
3118 
3119     return ajTrue;
3120 }
3121 
3122 
3123 
3124 
3125 /* @section destructors *******************************************************
3126 **
3127 ** Destruction destroys all internal data structures and frees the memory
3128 ** allocated for an Ensembl Mapper Range Registry object.
3129 **
3130 ** @fdata [EnsPMapperrangeregistry]
3131 **
3132 ** @nam3rule Del Destroy (free) an Ensembl Mapper Range Registry
3133 **
3134 ** @argrule * Pmrr [EnsPMapperrangeregistry*]
3135 ** Ensembl Mapper Range Registry address
3136 **
3137 ** @valrule * [void]
3138 **
3139 ** @fcategory delete
3140 ******************************************************************************/
3141 
3142 
3143 
3144 
3145 /* @func ensMapperrangeregistryDel ********************************************
3146 **
3147 ** Default destructor for an Ensembl Mapper Range Registry.
3148 **
3149 ** @param [d] Pmrr [EnsPMapperrangeregistry*]
3150 ** Ensembl Mapper Range Registry address
3151 **
3152 ** @return [void]
3153 **
3154 ** @release 6.2.0
3155 ** @@
3156 ******************************************************************************/
3157 
ensMapperrangeregistryDel(EnsPMapperrangeregistry * Pmrr)3158 void ensMapperrangeregistryDel(EnsPMapperrangeregistry *Pmrr)
3159 {
3160     EnsPMapperrangeregistry pthis = NULL;
3161 
3162     if (!Pmrr)
3163         return;
3164 
3165 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
3166     if (ajDebugTest("ensMapperrangeregistryDel"))
3167         ajDebug("ensMapperrangeregistryDel\n"
3168                 "  *Pmrr %p\n",
3169                 *Pmrr);
3170 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
3171 
3172     if (!(pthis = *Pmrr) || --pthis->Use)
3173     {
3174         *Pmrr = NULL;
3175 
3176         return;
3177     }
3178 
3179     ajTableDel(&pthis->Registry);
3180 
3181     ajMemFree((void **) Pmrr);
3182 
3183     return;
3184 }
3185 
3186 
3187 
3188 
3189 /* @section check *************************************************************
3190 **
3191 ** Check, whether coordinates have been registered before.
3192 **
3193 ** @fdata [EnsPMapperrangeregistry]
3194 **
3195 ** @nam3rule Check Check a coordinates
3196 **
3197 ** @argrule * mrr [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3198 ** @argrule Check oid [ajuint] Ensembl Object identifier
3199 ** @argrule Check chkstart [ajint] Start coordinate of the region to be checked
3200 ** @argrule Check chkend [ajint] End coordinate of the region to be checked
3201 ** @argrule Check regstart [ajint] Start coordinate of the region to register
3202 ** @argrule Check regend [ajint] End coordinate of the region to register
3203 ** @argrule Check ranges [AjPList] AJAX List of Ensembl Mapper Range objects
3204 **
3205 ** @valrule * [AjBool] ajTrue if already registered, ajFalse otherwise
3206 **
3207 ** @fcategory use
3208 ******************************************************************************/
3209 
3210 
3211 
3212 
3213 /* @func ensMapperrangeregistryCheck ******************************************
3214 **
3215 ** Check and register Ensembl Mapper Range objects in the
3216 ** Ensembl Mapper Range Registry.
3217 **
3218 ** @cc Bio::EnsEMBL::Mapper::RangeRegistry::check_and_register
3219 ** @param [u] mrr [EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3220 ** @param [r] oid [ajuint] Ensembl Object identifier
3221 ** @param [r] chkstart [ajint] Start coordinate of the region to be checked
3222 ** @param [r] chkend [ajint] End coordinate of the region to be checked
3223 ** @param [r] regstart [ajint] Start coordinate of the region to register
3224 ** @param [r] regend [ajint] End coordinate of the region to register
3225 ** @param [uN] ranges [AjPList] AJAX List of Ensembl Mapper Range objects
3226 **
3227 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3228 **
3229 ** @release 6.4.0
3230 ** @@
3231 **
3232 ** Checks the Ensembl Mapper Range Registry to see if the entire range denoted
3233 ** by (oid:chkstart-chkend) is already registered. If it already is, an empty
3234 ** AJAX List is returned. If it is not, then the range specified by regstart
3235 ** and regend is registered and an AJAX List of Ensembl Mapper Region objects
3236 ** that were required to completely register this region is returned.
3237 **
3238 ** If regstart and regend are not defined, they default to chkstart and chkend,
3239 ** respectively.
3240 **
3241 ** The reason, there is just a single function to do both the checking and
3242 ** registering is to reduce the overhead. Much of the work to check if a range
3243 ** is registered is the same as registering a region around that range.
3244 ******************************************************************************/
3245 
ensMapperrangeregistryCheck(EnsPMapperrangeregistry mrr,ajuint oid,ajint chkstart,ajint chkend,ajint regstart,ajint regend,AjPList ranges)3246 AjBool ensMapperrangeregistryCheck(EnsPMapperrangeregistry mrr,
3247                                    ajuint oid,
3248                                    ajint chkstart,
3249                                    ajint chkend,
3250                                    ajint regstart,
3251                                    ajint regend,
3252                                    AjPList ranges)
3253 {
3254     register ajuint i = 0U;
3255 
3256     ajuint idxstart  = 0U;
3257     ajuint idxmid    = 0U;
3258     ajuint idxend    = 0U;
3259     ajuint idxlength = 0U;
3260 
3261     ajuint idxregstart = 0U;
3262     ajuint idxregend   = 0U;
3263     ajuint idxregpos   = 0U;
3264 
3265     ajint gapstart = 0;
3266     ajint gapend   = 0;
3267     ajint newstart = 0;
3268     ajint newend   = 0;
3269 
3270     ajuint *Poid = NULL;
3271 
3272     AjBool idxregstartset = AJFALSE;
3273     AjBool idxregposset   = AJFALSE;
3274 
3275     AjIList iter = NULL;
3276     AjPList list = NULL;
3277 
3278     EnsPMapperrange range = NULL;
3279     EnsPMapperrange gap   = NULL;
3280 
3281     if (ajDebugTest("ensMapperrangeregistryCheck"))
3282         ajDebug("ensMapperrangeregistryCheck\n"
3283                 "  mrr %p\n"
3284                 "  oid %u\n"
3285                 "  chkstart %d\n"
3286                 "  chkend %d\n"
3287                 "  regstart %d (%#x)\n"
3288                 "  regend %d (%#x)\n"
3289                 "  ranges %p\n",
3290                 mrr,
3291                 oid,
3292                 chkstart,
3293                 chkend,
3294                 regstart, regstart,
3295                 regend, regend,
3296                 ranges);
3297 
3298     if (!mrr)
3299     {
3300         ajDebug("ensMapperrangeregistryCheck requires an "
3301                 "Ensembl Range Registry.\n");
3302 
3303         return ajFalse;
3304     }
3305 
3306     if (!oid)
3307         ajWarn("ensMapperrangeregistryCheck did not get a valid "
3308                "Ensembl Object identifier.\n");
3309 
3310     /*
3311     ** NOTE: Not applicable for circular genomes.
3312     if (chkstart > chkend)
3313     {
3314     ajWarn("ensMapperrangeregistryCheck requires the start "
3315     "coordinate (%d) to be less than or equal the end "
3316     "coordinate (%d) for the region to be checked.\n",
3317     chkstart, chkend);
3318 
3319     return ajFalse;
3320     }
3321     */
3322 
3323     if ((!regstart) && (!regend))
3324     {
3325         regstart = chkstart;
3326 
3327         regend = chkend;
3328     }
3329 
3330     /*
3331     ** NOTE: Not applicable for circular genomes.
3332     if (regstart > regend)
3333     {
3334     ajWarn("ensMapperrangeregistryCheck requires the start "
3335     "coordinate (%d) to be less than or equal the end "
3336     "coordinate (%d) for the region to be registered.\n",
3337     regstart, regend);
3338 
3339     return ajFalse;
3340     }
3341     */
3342 
3343     if (regstart > chkstart)
3344     {
3345         ajWarn("ensMapperrangeregistryCheck requires the start "
3346                "coordinate (%d) of the region to be registered to be less "
3347                "than or equal the start coordinate (%d) of the "
3348                "region to be checked.\n",
3349                regstart, chkstart);
3350 
3351         return ajFalse;
3352     }
3353 
3354     if (regend < chkend)
3355     {
3356         ajWarn("ensMapperrangeregistryCheck requires the end "
3357                "coordinate (%d) of the region to be registered to be less "
3358                "than or equal the end coordinate (%d) of the "
3359                "region to be checked.\n",
3360                regend, chkend);
3361 
3362         return ajFalse;
3363     }
3364 
3365     if (!mrr->Registry)
3366         ajFatal("ensMapperrangeregistryCheck got a "
3367                 "Mapper Range Registry without a valid AJAX Table.\n");
3368 
3369     list = (AjPList) ajTableFetchmodV(mrr->Registry, (const void *) &oid);
3370 
3371     if (!list)
3372     {
3373         AJNEW0(Poid);
3374 
3375         *Poid = oid;
3376 
3377         list = ajListNew();
3378 
3379         ajTablePut(mrr->Registry, (void *) Poid, (void *) list);
3380     }
3381 
3382     idxlength = (ajuint) ajListGetLength(list);
3383 
3384     if (!idxlength)
3385     {
3386         /*
3387         ** This is the first request for this Ensembl Object identifier,
3388         ** return a gap Mapper Range for the entire range and register it as
3389         ** seen.
3390         */
3391 
3392         range = ensMapperrangeNewIni(regstart, regend);
3393 
3394         ajListPushAppend(list, (void *) range);
3395 
3396         if (ranges)
3397             ajListPushAppend(ranges, (void *) ensMapperrangeNewRef(range));
3398 
3399         return ajTrue;
3400     }
3401 
3402     /*
3403     ** Loop through the AJAX List of existing Ensembl Mapper Range objects
3404     ** recording any "gaps" where the existing Mapper Range objects do not
3405     ** cover part of the requested range.
3406     */
3407 
3408     idxstart = 0U;
3409     idxend   = idxlength - 1U;
3410 
3411     /*
3412     ** Binary search the relevant Ensembl Mapper Range objects,
3413     ** which helps if the AJAX List of Ensembl Mapper Range objects is long.
3414     */
3415 
3416     while ((idxend - idxstart) > 1)
3417     {
3418         idxmid = (idxstart + idxend) >> 1;
3419 
3420         ajListPeekNumber(list, idxmid, (void **) &range);
3421 
3422         if (range->End < regstart)
3423             idxstart = idxmid;
3424         else
3425             idxend = idxmid;
3426     }
3427 
3428     gapstart = regstart;
3429 
3430     for (i = idxstart; i < idxlength; i++)
3431     {
3432         ajListPeekNumber(list, i, (void **) &range);
3433 
3434         /*
3435         ** No work needs to be done at all if we find a Mapper Range that
3436         ** entirely overlaps the requested region.
3437         */
3438 
3439         if ((range->Start <= chkstart) && (range->End >= chkend))
3440             return ajTrue;
3441 
3442         /* Find adjacent or overlapping regions already registered. */
3443 
3444         if ((range->Start <= (regend + 1)) && (range->End >= (regstart - 1)))
3445         {
3446             if (!idxregstartset)
3447             {
3448                 idxregstartset = ajTrue;
3449 
3450                 idxregstart = i;
3451             }
3452 
3453             idxregend = i;
3454         }
3455 
3456         /* Find previously un-registered regions (gaps). */
3457 
3458         if (range->Start > regstart)
3459         {
3460             gapend = (regend < range->Start) ? regend : (range->Start - 1);
3461 
3462             if (ranges)
3463             {
3464                 gap = ensMapperrangeNewIni(gapstart, gapend);
3465 
3466                 ajListPushAppend(ranges, (void *) gap);
3467             }
3468         }
3469 
3470         gapstart = (regstart > range->End) ? regstart : (range->End + 1);
3471 
3472         if ((range->End >= regend) && (!idxregposset))
3473         {
3474             idxregposset = ajTrue;
3475 
3476             idxregpos = i;
3477 
3478             break;
3479         }
3480     }
3481 
3482     /* Do we have to define another gap? */
3483 
3484     if ((gapstart <= regend) && ranges)
3485     {
3486         gap = ensMapperrangeNewIni(gapstart, regend);
3487 
3488         ajListPushAppend(ranges, (void *) gap);
3489     }
3490 
3491     /* Merge the new Ensembl Mapper Range into the AJAX List of registered. */
3492 
3493     if (idxregstartset)
3494     {
3495         /* Adjacent or overlapping regions have been found. */
3496 
3497         ajListPeekNumber(list, idxregstart, (void **) &range);
3498 
3499         newstart = (regstart < range->Start) ? regstart : range->Start;
3500 
3501         ajListPeekNumber(list, idxregend, (void **) &range);
3502 
3503         newend = (regend > range->End) ? regend : range->End;
3504 
3505         iter = ajListIterNew(list);
3506 
3507         /* Position the AJAX List Iterator at idxregstart. */
3508 
3509         for (i = 0U; i < idxregstart; i++)
3510             range = (EnsPMapperrange) ajListIterGet(iter);
3511 
3512         /*
3513         ** Now, remove idxregend - idxregstart + 1 elements
3514         ** from the AJAX List.
3515         */
3516 
3517         for (i = 0U; i < (idxregend - idxregstart + 1); i++)
3518         {
3519             range = (EnsPMapperrange) ajListIterGet(iter);
3520 
3521             ajListIterRemove(iter);
3522 
3523             ensMapperrangeDel(&range);
3524         }
3525 
3526         /* Finally, insert a new Mapper Range at the current position. */
3527 
3528         range = ensMapperrangeNewIni(newstart, newend);
3529 
3530         ajListIterInsert(iter, (void *) range);
3531 
3532         ajListIterDel(&iter);
3533     }
3534     else if (idxregposset)
3535     {
3536         iter = ajListIterNew(list);
3537 
3538         /* Position the AJAX List Iterator at idxregpos. */
3539 
3540         for (i = 0U; i < idxregpos; i++)
3541             range = (EnsPMapperrange) ajListIterGet(iter);
3542 
3543         /* Insert a new Mapper Range at this position. */
3544 
3545         range = ensMapperrangeNewIni(regstart, regend);
3546 
3547         ajListIterInsert(iter, (void *) range);
3548 
3549         ajListIterDel(&iter);
3550     }
3551     else
3552     {
3553         range = ensMapperrangeNewIni(regstart, regend);
3554 
3555         ajListPushAppend(list, (void *) range);
3556     }
3557 
3558     return ajTrue;
3559 }
3560 
3561 
3562 
3563 
3564 /* @section calculate *********************************************************
3565 **
3566 ** Functions for calculating values of an Ensembl Mapper Range Registry object.
3567 **
3568 ** @fdata [EnsPMapperrangeregistry]
3569 **
3570 ** @nam3rule Calculate Calculate Ensembl Mapper Range Registry values
3571 ** @nam4rule Mapperranges
3572 ** Calculate an AJAX List of Ensembl Mapper Range objects
3573 ** @nam4rule Memsize Calculate the memory size in bytes
3574 ** @nam4rule Overlap Calculate the overlap size
3575 **
3576 ** @argrule * mrr [const EnsPMapperrangeregistry] Ensembl Mapper Range Registry
3577 ** @argrule Mapperranges oid [ajuint] Ensembl Object identifier
3578 ** @argrule Overlap oid [ajuint] Ensembl Object identifier
3579 ** @argrule Overlap start [ajint] Start coordinate
3580 ** @argrule Overlap end [ajint] End coordinate
3581 **
3582 ** @valrule Mapperranges [const AjPList]
3583 ** AJAX List or Ensembl Mapper Range objects or NULL
3584 ** @valrule Memsize [size_t] Memory size in bytes or 0
3585 ** @valrule Overlap [ajuint] Overlap size or 0U
3586 **
3587 ** @fcategory misc
3588 ******************************************************************************/
3589 
3590 
3591 
3592 
3593 /* @func ensMapperrangeregistryCalculateMapperranges **************************
3594 **
3595 ** Calculate an AJAX List of Ensembl Mapper Range objects.
3596 **
3597 ** @cc Bio::EnsEMBL::Mapper::RangeRegistry::get_ranges
3598 ** @param [r] mrr [const EnsPMapperrangeregistry] Ensembl Mapper
3599 **                                                Range Registry
3600 ** @param [r] oid [ajuint] Ensembl Object identifier
3601 **
3602 ** @return [const AjPList] AJAX List of Ensembl Mapper Range objects or NULL
3603 **
3604 ** @release 6.4.0
3605 ** @@
3606 ******************************************************************************/
3607 
ensMapperrangeregistryCalculateMapperranges(const EnsPMapperrangeregistry mrr,ajuint oid)3608 const AjPList ensMapperrangeregistryCalculateMapperranges(
3609     const EnsPMapperrangeregistry mrr,
3610     ajuint oid)
3611 {
3612     if (!mrr)
3613         return NULL;
3614 
3615     if (!oid)
3616         return NULL;
3617 
3618     return (AjPList) ajTableFetchmodV(mrr->Registry, (const void *) &oid);
3619 }
3620 
3621 
3622 
3623 
3624 /* @func ensMapperrangeregistryCalculateOverlap *******************************
3625 **
3626 ** Calculate the overlap size of Ensembl Mapper Range objects in the
3627 ** Ensembl Mapper Range Registry. Finds out how many bases in the given range
3628 ** are already registered in an Ensembl Mapper Range Registry.
3629 **
3630 ** @cc Bio::EnsEMBL::Mapper::RangeRegistry::overlap_size
3631 ** @param [r] mrr [const EnsPMapperrangeregistry] Ensembl Mapper
3632 **                                                Range Registry
3633 ** @param [r] oid [ajuint] Ensembl Object identifier
3634 ** @param [r] start [ajint] Start coordinate
3635 ** @param [r] end [ajint] End coordinate
3636 **
3637 ** @return [ajuint] Overlap size or 0U
3638 **
3639 ** @release 6.4.0
3640 ** @@
3641 ******************************************************************************/
3642 
ensMapperrangeregistryCalculateOverlap(const EnsPMapperrangeregistry mrr,ajuint oid,ajint start,ajint end)3643 ajuint ensMapperrangeregistryCalculateOverlap(
3644     const EnsPMapperrangeregistry mrr,
3645     ajuint oid,
3646     ajint start,
3647     ajint end)
3648 {
3649     register ajuint i = 0U;
3650 
3651     ajuint idxstart  = 0U;
3652     ajuint idxmid    = 0U;
3653     ajuint idxend    = 0U;
3654     ajuint idxlength = 0U;
3655 
3656     ajint mrstart = 0;
3657     ajint mrend   = 0;
3658 
3659     ajuint overlap = 0U;
3660 
3661     AjPList list = NULL;
3662 
3663     EnsPMapperrange range = NULL;
3664 
3665     if (!mrr)
3666         return 0U;
3667 
3668     if (start > end)
3669         return 0U;
3670 
3671     list = (AjPList) ajTableFetchmodV(mrr->Registry, (const void *) &oid);
3672 
3673     if (!list)
3674         return 0U;
3675 
3676     idxlength = (ajuint) ajListGetLength(list);
3677 
3678     if (!idxlength)
3679         return 0U;
3680 
3681     idxstart = 0U;
3682     idxend   = idxlength - 1U;
3683 
3684     /*
3685     ** Binary search the relevant Ensembl Mapper Range objects,
3686     ** which helps if the AJAX List is long.
3687     */
3688 
3689     while ((idxend - idxstart) > 1)
3690     {
3691         idxmid = (idxstart + idxend) >> 1;
3692 
3693         ajListPeekNumber(list, idxmid, (void **) &range);
3694 
3695         if (range->End < start)
3696             idxstart = idxmid;
3697         else
3698             idxend = idxmid;
3699     }
3700 
3701     for (i = idxstart; i < idxlength; i++)
3702     {
3703         ajListPeekNumber(list, i, (void **) &range);
3704 
3705         /*
3706         ** Check, wheher the loop has already overrun.
3707         ** If that was the case, there are no more interesting Mapper Range
3708         ** objects.
3709         */
3710 
3711         if (range->Start > start)
3712             break;
3713 
3714         /*
3715         ** No work needs to be done at all if we find a Mapper Range that
3716         ** entirely overlaps the requested region.
3717         */
3718 
3719         if ((range->Start <= start) && (range->End >= end))
3720         {
3721             overlap = (ajuint) (end - start + 1);
3722 
3723             break;
3724         }
3725 
3726         mrstart = (start < range->Start) ? range->Start : start;
3727 
3728         mrend = (end < range->End) ? end : range->End;
3729 
3730         if ((mrend - mrstart) >= 0)
3731             overlap += (ajuint) (mrend - mrstart + 1);
3732     }
3733 
3734     return overlap;
3735 }
3736 
3737 
3738 
3739 
3740 /* @datasection [EnsPMapper] Ensembl Mapper ***********************************
3741 **
3742 ** @nam2rule Mapper Functions for manipulating Ensembl Mapper objects
3743 **
3744 ** @cc Bio::EnsEMBL::Mapper
3745 ** @cc CVS Revision: 1.60
3746 ** @cc CVS Tag: branch-ensembl-68
3747 **
3748 ******************************************************************************/
3749 
3750 
3751 
3752 
3753 /* @section constructors ******************************************************
3754 **
3755 ** All constructors return a new Ensembl Mapper by pointer.
3756 ** It is the responsibility of the user to first destroy any previous
3757 ** Mapper. The target pointer does not need to be initialised to
3758 ** NULL, but it is good programming practice to do so anyway.
3759 **
3760 ** @fdata [EnsPMapper]
3761 **
3762 ** @nam3rule New Constructor
3763 ** @nam4rule Cpy Constructor with existing object
3764 ** @nam4rule Ini Constructor with initial values
3765 ** @nam4rule Ref Constructor by incrementing the reference counter
3766 **
3767 ** @argrule Cpy mapper [const EnsPMapper] Ensembl Mapper
3768 ** @argrule Ini srctype [AjPStr] Source type
3769 ** @argrule Ini trgtype [AjPStr] Target type
3770 ** @argrule Ini srccs [EnsPCoordsystem] Source Ensembl Coordinate System
3771 ** @argrule Ini trgcs [EnsPCoordsystem] Target Ensembl Coordinate System
3772 ** @argrule Ref mapper [EnsPMapper] Ensembl Mapper
3773 **
3774 ** @valrule * [EnsPMapper] Ensembl Mapper or NULL
3775 **
3776 ** @fcategory new
3777 ******************************************************************************/
3778 
3779 
3780 
3781 
3782 /* @funcstatic mapperListMapperpairValdel *************************************
3783 **
3784 ** An ajTableSetDestroyvalue "valdel" function to clear AJAX Table value data.
3785 ** This function removes and deletes Ensembl Mapper Pair objects
3786 ** from an AJAX List object, before deleting the AJAX List object.
3787 **
3788 ** @param [d] Pvalue [void**] AJAX List address
3789 ** @see ajTableSetDestroyvalue
3790 **
3791 ** @return [void]
3792 **
3793 ** @release 6.4.0
3794 ** @@
3795 ******************************************************************************/
3796 
mapperListMapperpairValdel(void ** Pvalue)3797 static void mapperListMapperpairValdel(void **Pvalue)
3798 {
3799     EnsPMapperpair mp = NULL;
3800 
3801     if (!Pvalue)
3802         return;
3803 
3804     if (!*Pvalue)
3805         return;
3806 
3807     while (ajListPop(*((AjPList *) Pvalue), (void **) &mp))
3808         ensMapperpairDel(&mp);
3809 
3810     ajListFree((AjPList *) Pvalue);
3811 
3812     return;
3813 }
3814 
3815 
3816 
3817 
3818 /* @func ensMapperNewIni ******************************************************
3819 **
3820 ** Constructor for an Ensembl Mapper with initial values.
3821 **
3822 ** @cc Bio::EnsEMBL::Mapper::new
3823 ** @param [u] srctype [AjPStr] Source type
3824 ** @param [u] trgtype [AjPStr] Target type
3825 ** @param [u] srccs [EnsPCoordsystem] Source Ensembl Coordinate System
3826 ** @param [u] trgcs [EnsPCoordsystem] Target Ensembl Coordinate System
3827 **
3828 ** @return [EnsPMapper] Ensembl Mapper or NULL
3829 **
3830 ** @release 6.4.0
3831 ** @@
3832 ******************************************************************************/
3833 
ensMapperNewIni(AjPStr srctype,AjPStr trgtype,EnsPCoordsystem srccs,EnsPCoordsystem trgcs)3834 EnsPMapper ensMapperNewIni(AjPStr srctype,
3835                            AjPStr trgtype,
3836                            EnsPCoordsystem srccs,
3837                            EnsPCoordsystem trgcs)
3838 {
3839     AjPTable table = NULL;
3840 
3841     EnsPMapper mapper = NULL;
3842 
3843     if (ajDebugTest("ensMapperNewIni"))
3844     {
3845         ajDebug("ensMapperNewIni\n"
3846                 "  srctype '%S'\n"
3847                 "  trgtype '%S'\n"
3848                 "  srccs %p\n"
3849                 "  trgcs %p\n",
3850                 srctype,
3851                 trgtype,
3852                 srccs,
3853                 trgcs);
3854 
3855         ensCoordsystemTrace(srccs, 1);
3856         ensCoordsystemTrace(trgcs, 1);
3857     }
3858 
3859     if (!srctype)
3860         return NULL;
3861 
3862     if (!trgtype)
3863         return NULL;
3864 
3865     if (!srccs)
3866         return NULL;
3867 
3868     if (!trgcs)
3869         return NULL;
3870 
3871     AJNEW0(mapper);
3872 
3873     mapper->TypeSource        = ajStrNewRef(srctype);
3874     mapper->TypeTarget        = ajStrNewRef(trgtype);
3875     mapper->CoordsystemSource = ensCoordsystemNewRef(srccs);
3876     mapper->CoordsystemTarget = ensCoordsystemNewRef(trgcs);
3877     mapper->Mapperpairs       = ajTablestrNew(0U);
3878     mapper->Count             = 0U;
3879     mapper->Sorted            = ajFalse;
3880     mapper->Use               = 1U;
3881 
3882     ajTableSetDestroyvalue(
3883         mapper->Mapperpairs,
3884         (void (*)(void **)) &ajTableDel);
3885 
3886     /*
3887     ** Initialise second-level AJAX Table objects with Ensembl Object
3888     ** identifier keys and put them into the first-level AJAX Table indexed on
3889     ** source and target types.
3890     */
3891 
3892     table = ajTableuintNew(0U);
3893 
3894     ajTableSetDestroyvalue(
3895         table,
3896         (void (*)(void **)) &mapperListMapperpairValdel);
3897 
3898     ajTablePut(mapper->Mapperpairs, (void *) ajStrNewS(srctype), (void *) table);
3899 
3900     table = ajTableuintNew(0U);
3901 
3902     ajTableSetDestroyvalue(
3903         table,
3904         (void (*)(void **)) &mapperListMapperpairValdel);
3905 
3906     ajTablePut(mapper->Mapperpairs, (void *) ajStrNewS(trgtype), (void *) table);
3907 
3908     return mapper;
3909 }
3910 
3911 
3912 
3913 
3914 /* @func ensMapperNewRef ******************************************************
3915 **
3916 ** Ensembl Object referencing function, which returns a pointer to the
3917 ** Ensembl Object passed in and increases its reference count.
3918 **
3919 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
3920 **
3921 ** @return [EnsPMapper] Ensembl Mapper or NULL
3922 **
3923 ** @release 6.2.0
3924 ** @@
3925 ******************************************************************************/
3926 
ensMapperNewRef(EnsPMapper mapper)3927 EnsPMapper ensMapperNewRef(EnsPMapper mapper)
3928 {
3929     if (!mapper)
3930         return NULL;
3931 
3932     mapper->Use++;
3933 
3934     return mapper;
3935 }
3936 
3937 
3938 
3939 
3940 /* @section clear *************************************************************
3941 **
3942 ** Clear all internal data structures and frees the
3943 ** memory allocated for Ensembl Mapper internals.
3944 **
3945 ** @fdata [EnsPMapper]
3946 **
3947 ** @nam3rule Clear Clear (free) an Ensembl Mapper object
3948 **
3949 ** @argrule * mapper [EnsPMapper] Ensembl Mapper
3950 **
3951 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
3952 **
3953 ** @fcategory delete
3954 ******************************************************************************/
3955 
3956 
3957 
3958 
3959 /* @funcstatic mapperMapperpairsClear *****************************************
3960 **
3961 ** An ajTableMap "apply" function to process an AJAX Table of
3962 ** AJAX String object key data and
3963 ** AJAX Table object value data.
3964 ** This function also clears and deletes the secondary AJAX Table objects via
3965 ** mapperClearL2.
3966 **
3967 ** @param [r] key [const void*] AJAX String address
3968 ** @param [u] Pvalue [void**] AJAX Table address
3969 ** @param [u] cl [void*] Standard, passed in from ajTableMapDel
3970 ** @see ajTableMap
3971 **
3972 ** @return [void]
3973 **
3974 ** @release 6.4.0
3975 ** @@
3976 ******************************************************************************/
3977 
mapperMapperpairsClear(const void * key,void ** Pvalue,void * cl)3978 static void mapperMapperpairsClear(const void *key,
3979                                    void **Pvalue,
3980                                    void *cl)
3981 {
3982     if (!Pvalue)
3983         return;
3984 
3985     if (!*Pvalue)
3986         return;
3987 
3988     (void) cl;
3989 
3990     (void) key;
3991 
3992     ajTableClearDelete(*((AjPTable *) Pvalue));
3993 
3994     return;
3995 }
3996 
3997 
3998 
3999 
4000 /* @func ensMapperClear *******************************************************
4001 **
4002 ** Clear an Ensembl Mapper.
4003 **
4004 ** This function processes the first-level AJAX Table of
4005 ** AJAX String object (Ensembl Mapper type) key data and
4006 ** second-level AJAX Table object value data.
4007 ** The second-level AJAX Table of
4008 ** AJAX unsigned integer (Ensembl Object identifier) key data and
4009 ** third-level AJAX List object valude data are cleared.
4010 ** The third-level AJAX List objects of Ensembl Mapper Pair objects are cleared
4011 ** and deleted, as are the Ensembl Mapper Pair objects.
4012 **
4013 ** @cc Bio::EnsEMBL::Mapper::flush
4014 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4015 **
4016 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4017 **
4018 ** @release 6.2.0
4019 ** @@
4020 ******************************************************************************/
4021 
ensMapperClear(EnsPMapper mapper)4022 AjBool ensMapperClear(EnsPMapper mapper)
4023 {
4024     if (ajDebugTest("ensMapperClear"))
4025     {
4026         ajDebug("ensMapperClear\n"
4027                 "  mapper %p\n",
4028                 mapper);
4029 
4030         ensMapperTrace(mapper, 1);
4031     }
4032 
4033     if (!mapper)
4034         return ajFalse;
4035 
4036     ajTableMap(mapper->Mapperpairs, &mapperMapperpairsClear, NULL);
4037 
4038     mapper->Count = 0;
4039     mapper->Sorted = ajFalse;
4040 
4041     return ajTrue;
4042 }
4043 
4044 
4045 
4046 
4047 /* @section destructors *******************************************************
4048 **
4049 ** Destruction destroys all internal data structures and frees the memory
4050 ** allocated for an Ensembl Mapper object.
4051 **
4052 ** @fdata [EnsPMapper]
4053 **
4054 ** @nam3rule Del Destroy (free) an Ensembl Mapper
4055 **
4056 ** @argrule * Pmapper [EnsPMapper*] Ensembl Mapper address
4057 **
4058 ** @valrule * [void]
4059 **
4060 ** @fcategory delete
4061 ******************************************************************************/
4062 
4063 
4064 
4065 
4066 /* @func ensMapperDel *********************************************************
4067 **
4068 ** Default destructor for an Ensembl Mapper.
4069 **
4070 ** This function clears and deletes the first-level AJAX Table of
4071 ** AJAX String object (Ensembl Mapper type) key data and
4072 ** second-level AJAX Table object value data.
4073 ** The second-level AJAX Table of
4074 ** AJAX unsigned integer (Ensembl Object identifier) key data and
4075 ** third-level AJAX List object value data are also cleared.
4076 ** The third-level AJAX List objects of Ensembl Mapper Pair objects are cleared
4077 ** and deleted, as are the Ensembl Mapper Pair objects.
4078 **
4079 ** @param [d] Pmapper [EnsPMapper*] Ensembl Mapper address
4080 **
4081 ** @return [void]
4082 **
4083 ** @release 6.2.0
4084 ** @@
4085 ******************************************************************************/
4086 
ensMapperDel(EnsPMapper * Pmapper)4087 void ensMapperDel(EnsPMapper *Pmapper)
4088 {
4089     EnsPMapper pthis = NULL;
4090 
4091     if (!Pmapper)
4092         return;
4093 
4094 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
4095     if (ajDebugTest("ensMapperDel"))
4096     {
4097         ajDebug("ensMapperDel\n"
4098                 "  *Pmapper %p\n",
4099                 *Pmapper);
4100 
4101         ensMapperTrace(*Pmapper, 1);
4102     }
4103 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
4104 
4105     if (!(pthis = *Pmapper) || --pthis->Use)
4106     {
4107         *Pmapper = NULL;
4108 
4109         return;
4110     }
4111 
4112     ajTableDel(&pthis->Mapperpairs);
4113 
4114     ajStrDel(&pthis->TypeSource);
4115     ajStrDel(&pthis->TypeTarget);
4116 
4117     ensCoordsystemDel(&pthis->CoordsystemSource);
4118     ensCoordsystemDel(&pthis->CoordsystemTarget);
4119 
4120     ajMemFree((void **) Pmapper);
4121 
4122     return;
4123 }
4124 
4125 
4126 
4127 
4128 /* @section member retrieval **************************************************
4129 **
4130 ** Functions for returning members of an Ensembl Mapper object.
4131 **
4132 ** @fdata [EnsPMapper]
4133 **
4134 ** @nam3rule Get Return Ensembl Mapper attribute(s)
4135 ** @nam4rule Coordsystem Return an Ensembl Coordinate System
4136 ** @nam5rule Source Return the source Ensembl Coordinate System
4137 ** @nam5rule Target Return the target Ensembl Coordinate System
4138 ** @nam4rule Count Return the number of Ensembl Mapper Pair objects
4139 ** @nam4rule Sorted Return the sorted attribute
4140 ** @nam4rule Type Return an Ensembl Mapper Type
4141 ** @nam5rule Source Return the source type
4142 ** @nam5rule Target Return the target type
4143 **
4144 ** @argrule * mapper [const EnsPMapper] Ensembl Mapper
4145 **
4146 ** @valrule CoordsystemSource [EnsPCoordsystem] Source Ensembl Coordinate
4147 ** System or NULL
4148 ** @valrule CoordsystemTarget [EnsPCoordsystem] Target Ensembl Coordinate
4149 ** System or NULL
4150 ** @valrule Count [ajuint] Number of Ensembl Mapper Pair objects or 0U
4151 ** @valrule Sorted [AjBool] ajTrue if the Mapper Pair objects are sorted
4152 ** @valrule TypeSource [AjPStr] Source type or NULL
4153 ** @valrule TypeTarget [AjPStr] Target type or NULL
4154 **
4155 ** @fcategory use
4156 ******************************************************************************/
4157 
4158 
4159 
4160 
4161 /* @func ensMapperGetCoordsystemSource ****************************************
4162 **
4163 ** Get the source Ensembl Coordinate System member of an Ensembl Mapper.
4164 **
4165 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4166 **
4167 ** @return [EnsPCoordsystem] Source Ensembl Coordinate System or NULL
4168 **
4169 ** @release 6.4.0
4170 ** @@
4171 ******************************************************************************/
4172 
ensMapperGetCoordsystemSource(const EnsPMapper mapper)4173 EnsPCoordsystem ensMapperGetCoordsystemSource(const EnsPMapper mapper)
4174 {
4175     return (mapper) ? mapper->CoordsystemSource : NULL;
4176 }
4177 
4178 
4179 
4180 
4181 /* @func ensMapperGetCoordsystemTarget ****************************************
4182 **
4183 ** Get the target Ensembl Coordinate System member of an Ensembl Mapper.
4184 **
4185 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4186 **
4187 ** @return [EnsPCoordsystem] Target Ensembl Coordinate System or NULL
4188 **
4189 ** @release 6.4.0
4190 ** @@
4191 ******************************************************************************/
4192 
ensMapperGetCoordsystemTarget(const EnsPMapper mapper)4193 EnsPCoordsystem ensMapperGetCoordsystemTarget(const EnsPMapper mapper)
4194 {
4195     return (mapper) ? mapper->CoordsystemTarget : NULL;
4196 }
4197 
4198 
4199 
4200 
4201 /* @func ensMapperGetCount ****************************************************
4202 **
4203 ** Get the number of Ensembl Mapper Pair objects in an Ensembl Mapper.
4204 **
4205 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4206 **
4207 ** @return [ajuint] Number of Ensembl Mapper Pair objects or 0U
4208 **
4209 ** @release 6.4.0
4210 ** @@
4211 ******************************************************************************/
4212 
ensMapperGetCount(const EnsPMapper mapper)4213 ajuint ensMapperGetCount(const EnsPMapper mapper)
4214 {
4215     return (mapper) ? mapper->Count : 0U;
4216 }
4217 
4218 
4219 
4220 
4221 /* @func ensMapperGetSorted ***************************************************
4222 **
4223 ** Return the sorted member of an Ensembl Mapper.
4224 **
4225 ** This member indicates whether Ensembl Mapper Pair objects are sorted
4226 ** in the Ensembl Mapper.
4227 **
4228 ** @cc Bio::EnsEMBL::Mapper::_is_sorted
4229 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4230 **
4231 ** @return [AjBool] ajTrue if the Mapper Pair objects are sorted
4232 **
4233 ** @release 6.4.0
4234 ** @@
4235 ******************************************************************************/
4236 
ensMapperGetSorted(const EnsPMapper mapper)4237 AjBool ensMapperGetSorted(const EnsPMapper mapper)
4238 {
4239     return (mapper) ? mapper->Sorted : ajFalse;
4240 }
4241 
4242 
4243 
4244 
4245 /* @func ensMapperGetTypeSource ***********************************************
4246 **
4247 ** Get the source type member of an Ensembl Mapper.
4248 **
4249 ** @cc Bio::EnsEMBL::Mapper::from
4250 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4251 **
4252 ** @return [AjPStr] Source type or NULL
4253 **
4254 ** @release 6.4.0
4255 ** @@
4256 ******************************************************************************/
4257 
ensMapperGetTypeSource(const EnsPMapper mapper)4258 AjPStr ensMapperGetTypeSource(const EnsPMapper mapper)
4259 {
4260     return (mapper) ? mapper->TypeSource : NULL;
4261 }
4262 
4263 
4264 
4265 
4266 /* @func ensMapperGetTypeTarget ***********************************************
4267 **
4268 ** Get the target type member of an Ensembl Mapper.
4269 **
4270 ** @cc Bio::EnsEMBL::Mapper::to
4271 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
4272 **
4273 ** @return [AjPStr] Target type or NULL
4274 **
4275 ** @release 6.4.0
4276 ** @@
4277 ******************************************************************************/
4278 
ensMapperGetTypeTarget(const EnsPMapper mapper)4279 AjPStr ensMapperGetTypeTarget(const EnsPMapper mapper)
4280 {
4281     return (mapper) ? mapper->TypeTarget : NULL;
4282 }
4283 
4284 
4285 
4286 
4287 /* @funcstatic mapperMapperpairsMerge *****************************************
4288 **
4289 ** Merge adjacent Ensembl Mapper Pair objects in an Ensembl Mapper into one.
4290 **
4291 ** @cc Bio::EnsEMBL::Mapper::_merge_pairs
4292 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4293 **
4294 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4295 **
4296 ** @release 6.2.0
4297 ** @@
4298 ******************************************************************************/
4299 
mapperMapperpairsMerge(EnsPMapper mapper)4300 static AjBool mapperMapperpairsMerge(EnsPMapper mapper)
4301 {
4302     void **valarray = NULL;
4303 
4304     register ajuint i = 0U;
4305 
4306     AjBool debug = AJFALSE;
4307 
4308     AjIList srciter = NULL;
4309     AjIList trgiter = NULL;
4310 
4311     AjPList srclist = NULL;
4312     AjPList trglist = NULL;
4313 
4314     AjPTable srctable = NULL;
4315     AjPTable trgtable = NULL;
4316 
4317     EnsPMapperpair delpair  = NULL;
4318     EnsPMapperpair srcpair  = NULL;
4319     EnsPMapperpair trgpair1 = NULL;
4320     EnsPMapperpair trgpair2 = NULL;
4321 
4322     debug = ajDebugTest("mapperMapperpairsMerge");
4323 
4324     if (debug)
4325     {
4326         ajDebug("mapperMapperpairsMerge\n"
4327                 "  mapper %p\n",
4328                 mapper);
4329 
4330         ensMapperTrace(mapper, 1);
4331     }
4332 
4333     if (!mapper)
4334         return ajFalse;
4335 
4336     trgtable = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
4337                                            mapper->TypeTarget);
4338 
4339     ajTableToarrayValues(trgtable, &valarray);
4340 
4341     for (i = 0U; valarray[i]; i++)
4342     {
4343         trglist = (AjPList) valarray[i];
4344 
4345         trgiter = ajListIterNew(trglist);
4346 
4347         while (!ajListIterDone(trgiter))
4348         {
4349             trgpair1 = (EnsPMapperpair) ajListIterGet(trgiter);
4350             trgpair2 = (EnsPMapperpair) ajListIterGet(trgiter);
4351 
4352             /*
4353             ** If target Mapper Pair 2 is not defined, there are no more
4354             ** Mapper Pair objects to compare.
4355             */
4356 
4357             if ((!trgpair1) || (!trgpair2))
4358                 break;
4359 
4360             /* Do not merge insertion or deletion Mapper Pair objects. */
4361 
4362             if (trgpair1->Indel || trgpair2->Indel)
4363                 continue;
4364 
4365             assert(trgpair1->Source);
4366             assert(trgpair1->Target);
4367 
4368             assert(trgpair2->Source);
4369             assert(trgpair2->Target);
4370 
4371             /* Merge overlapping Mapper Pair objects. */
4372 
4373             if ((trgpair1->Source->Objectidentifier ==
4374                  trgpair2->Source->Objectidentifier) &&
4375                 (trgpair1->Target->Start == trgpair2->Target->Start))
4376                 delpair = trgpair2;
4377             /* Merge adjacent Mapper Pair objects. */
4378             else if ((trgpair1->Source->Objectidentifier ==
4379                       trgpair2->Source->Objectidentifier) &&
4380                      (trgpair1->Orientation == trgpair2->Orientation) &&
4381                      (trgpair1->Target->End == (trgpair2->Target->Start - 1)))
4382             {
4383                 if (trgpair1->Orientation >= 0)
4384                 {
4385                     /* Check for a potential parallel merge. */
4386 
4387                     if (trgpair1->Source->End == (trgpair2->Source->Start - 1))
4388                     {
4389                         if (debug)
4390                         {
4391                             ajDebug("mapperMapperpairsMerge merged %p with %p "
4392                                     "in parallel orientation.\n",
4393                                     trgpair1, trgpair2);
4394 
4395                             ensMapperpairTrace(trgpair1, 1);
4396                             ensMapperpairTrace(trgpair2, 1);
4397                         }
4398 
4399                         /* Merge in parallel orientation. */
4400 
4401                         trgpair1->Source->End = trgpair2->Source->End;
4402                         trgpair1->Target->End = trgpair2->Target->End;
4403 
4404                         delpair = trgpair2;
4405                     }
4406                 }
4407                 else
4408                 {
4409                     /* Check for a potential anti-parallel merge. */
4410 
4411                     if (trgpair1->Source->Start == (trgpair2->Source->End + 1))
4412                     {
4413                         if (debug)
4414                         {
4415                             ajDebug("mapperMapperpairsMerge merged %p with %p "
4416                                     "in anti-parallel orientation.\n",
4417                                     trgpair1, trgpair2);
4418 
4419                             ensMapperpairTrace(trgpair1, 1);
4420                             ensMapperpairTrace(trgpair2, 1);
4421                         }
4422 
4423                         /* Merge in anti-parallel orientation. */
4424 
4425                         trgpair1->Source->Start = trgpair2->Source->Start;
4426                         trgpair1->Target->End   = trgpair2->Target->End;
4427 
4428                         delpair = trgpair2;
4429                     }
4430                 }
4431             }
4432 
4433             /* Remove the redundant Mapper Pair also from the source Table. */
4434 
4435             if (delpair)
4436             {
4437                 ajListIterRemove(trgiter);
4438 
4439                 srctable = (AjPTable) ajTableFetchmodS(
4440                     mapper->Mapperpairs,
4441                     mapper->TypeSource);
4442 
4443                 srclist = (AjPList) ajTableFetchmodV(
4444                     srctable,
4445                     (const void *) &delpair->Source->Objectidentifier);
4446 
4447                 srciter = ajListIterNew(srclist);
4448 
4449                 while (!ajListIterDone(srciter))
4450                 {
4451                     srcpair = (EnsPMapperpair) ajListIterGet(srciter);
4452 
4453                     if (srcpair == delpair)
4454                     {
4455                         ajListIterRemove(srciter);
4456 
4457                         ensMapperpairDel(&srcpair);
4458                     }
4459                 }
4460 
4461                 ajListIterDel(&srciter);
4462 
4463                 ensMapperpairDel(&delpair);
4464             }
4465         }
4466 
4467         ajListIterDel(&trgiter);
4468 
4469         mapper->Count = (ajuint) ajListGetLength(trglist);
4470     }
4471 
4472     AJFREE(valarray);
4473 
4474     return ajTrue;
4475 }
4476 
4477 
4478 
4479 
4480 /* @funcstatic mapperMapperpairsSort ******************************************
4481 **
4482 ** Sort Ensembl Mapper Pair objects in an Ensembl Mapper.
4483 ** @cc Bio::EnsEMBL::Mapper::_sort
4484 **
4485 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4486 **
4487 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4488 **
4489 ** @release 6.2.0
4490 ** @@
4491 ******************************************************************************/
4492 
mapperMapperpairsSort(EnsPMapper mapper)4493 static AjBool mapperMapperpairsSort(EnsPMapper mapper)
4494 {
4495     void **valarray = NULL;
4496 
4497     register ajuint i = 0U;
4498 
4499     AjPTable table = NULL;
4500 
4501     if (ajDebugTest("mapperMapperpairsSort"))
4502     {
4503         ajDebug("mapperMapperpairsSort\n"
4504                 "  mapper %p\n",
4505                 mapper);
4506 
4507         ensMapperTrace(mapper, 1);
4508     }
4509 
4510     if (!mapper)
4511         return ajFalse;
4512 
4513     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
4514                                         mapper->TypeSource);
4515 
4516     ajTableToarrayValues(table, &valarray);
4517 
4518     for (i = 0U; valarray[i]; i++)
4519         ensListMapperpairSortSourceStartAscending((AjPList) valarray[i]);
4520 
4521     AJFREE(valarray);
4522 
4523     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
4524                                         mapper->TypeTarget);
4525 
4526     ajTableToarrayValues(table, &valarray);
4527 
4528     for (i = 0U; valarray[i]; i++)
4529         ensListMapperpairSortTargetStartAscending((AjPList) valarray[i]);
4530 
4531     AJFREE(valarray);
4532 
4533     mapperMapperpairsMerge(mapper);
4534 
4535     mapper->Sorted = ajTrue;
4536 
4537     return ajTrue;
4538 }
4539 
4540 
4541 
4542 
4543 /* @section member addition ***************************************************
4544 **
4545 ** Functions for adding members to an Ensembl Mapper object.
4546 **
4547 ** @fdata [EnsPMapper]
4548 **
4549 ** @nam3rule Add Add one object to an Ensembl Mapper
4550 ** @nam4rule Coordinates Add coordinates
4551 ** @nam4rule Indel       Add insertion-deletion coordinates
4552 ** @nam4rule Mapperpair  Add an Ensembl Mapper Pair
4553 ** @nam4rule Mappers     Add an Ensembl Mapper
4554 ** @nam4rule Mapperunits Add an Ensembl Mapper Unit pair
4555 **
4556 ** @argrule Coordinates mapper [EnsPMapper] Ensembl Mapper
4557 ** @argrule Coordinates srcoid [ajuint] Source Object identifier
4558 ** @argrule Coordinates srcstart [ajint] Source start coordinate
4559 ** @argrule Coordinates srcend [ajint] Source end coordinate
4560 ** @argrule Coordinates ori [ajint] Orientation
4561 ** @argrule Coordinates trgoid [ajuint] Target Object identifier
4562 ** @argrule Coordinates trgstart [ajint] Target start coordinate
4563 ** @argrule Coordinates trgend [ajint] Target end coordinate
4564 ** @argrule Indel mapper [EnsPMapper] Ensembl Mapper
4565 ** @argrule Indel srcoid [ajuint] Source Object identifier
4566 ** @argrule Indel srcstart [ajint] Source start coordinate
4567 ** @argrule Indel srcend [ajint] Source end coordinate
4568 ** @argrule Indel ori [ajint] Orientation
4569 ** @argrule Indel trgoid [ajuint] Target Object identifier
4570 ** @argrule Indel trgstart [ajint] Target start coordinate
4571 ** @argrule Indel trgend [ajint] Target end coordinate
4572 ** @argrule Mapperpair mapper [EnsPMapper] Ensembl Mapper
4573 ** @argrule Mapperpair mp [EnsPMapperpair] Ensembl Mapper Pair
4574 ** @argrule Mappers mapper1 [EnsPMapper] Ensembl Mapper
4575 ** @argrule Mappers mapper2 [EnsPMapper] Ensembl Mapper
4576 ** @argrule Mapperunits mapper [EnsPMapper] Ensembl Mapper
4577 ** @argrule Mapperunits srcmu [EnsPMapperunit] Source Ensembl Mapper Unit
4578 ** @argrule Mapperunits trgmu [EnsPMapperunit] Target Ensembl Mapper Unit
4579 ** @argrule Mapperunits ori [ajint] Relative orientation of the Ensembl Mapper
4580 ** Unit objects
4581 ** @argrule Mapperunits indel [AjBool] Insertion-deletion attribute
4582 **
4583 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
4584 **
4585 ** @fcategory modify
4586 ******************************************************************************/
4587 
4588 
4589 
4590 
4591 /* @func ensMapperAddCoordinates **********************************************
4592 **
4593 ** Store details of mapping between a source and a target region.
4594 **
4595 ** @cc Bio::EnsEMBL::Mapper::add_map_coordinates
4596 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4597 ** @param [r] srcoid [ajuint] Source Object identifier
4598 ** @param [r] srcstart [ajint] Source start coordinate
4599 ** @param [r] srcend [ajint] Source end coordinate
4600 ** @param [r] ori [ajint] Orientation
4601 ** @param [r] trgoid [ajuint] Target Object identifier
4602 ** @param [r] trgstart [ajint] Target start coordinate
4603 ** @param [r] trgend [ajint] Target end coordinate
4604 **
4605 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4606 **
4607 ** @release 6.2.0
4608 ** @@
4609 ******************************************************************************/
4610 
ensMapperAddCoordinates(EnsPMapper mapper,ajuint srcoid,ajint srcstart,ajint srcend,ajint ori,ajuint trgoid,ajint trgstart,ajint trgend)4611 AjBool ensMapperAddCoordinates(EnsPMapper mapper,
4612                                ajuint srcoid,
4613                                ajint srcstart,
4614                                ajint srcend,
4615                                ajint ori,
4616                                ajuint trgoid,
4617                                ajint trgstart,
4618                                ajint trgend)
4619 {
4620     AjBool result = AJFALSE;
4621 
4622     EnsPMapperpair mp = NULL;
4623 
4624     if (ajDebugTest("ensMapperAddCoordinates"))
4625         ajDebug("ensMapperAddCoordinates\n"
4626                 "  mapper %p\n"
4627                 "  srcoid %u\n"
4628                 "  srcstart %d\n"
4629                 "  srcend %d\n"
4630                 "  ori %d\n"
4631                 "  trgoid %u\n"
4632                 "  trgstart %d\n"
4633                 "  trgend %d\n",
4634                 mapper,
4635                 srcoid,
4636                 srcstart,
4637                 srcend,
4638                 ori,
4639                 trgoid,
4640                 trgstart,
4641                 trgend);
4642 
4643     if (!mapper)
4644         return ajFalse;
4645 
4646     if (!srcoid)
4647         return ajFalse;
4648 
4649     if (!trgoid)
4650         return ajFalse;
4651 
4652     if ((srcend - srcstart) != (trgend - trgstart))
4653         ajFatal("ensMapperAddCoordinates cannot deal with mis-lengthed "
4654                 "mappings so far.\n");
4655 
4656     mp = ensMapperpairNewIni(srcoid, srcstart, srcend,
4657                              trgoid, trgstart, trgend,
4658                              ori, ajFalse);
4659 
4660     result = ensMapperAddMapperpair(mapper, mp);
4661 
4662     ensMapperpairDel(&mp);
4663 
4664     return result;
4665 }
4666 
4667 
4668 
4669 
4670 /* @func ensMapperAddIndel ****************************************************
4671 **
4672 ** Store details of mapping between a source and a target region.
4673 **
4674 ** @cc Bio::EnsEMBL::Mapper::add_indel_coordinates
4675 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4676 ** @param [r] srcoid [ajuint] Source Object identifier
4677 ** @param [r] srcstart [ajint] Source start coordinate
4678 ** @param [r] srcend [ajint] Source end coordinate
4679 ** @param [r] ori [ajint] Orientation
4680 ** @param [r] trgoid [ajuint] Target Object identifier
4681 ** @param [r] trgstart [ajint] Target start coordinate
4682 ** @param [r] trgend [ajint] Target end coordinate
4683 **
4684 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4685 **
4686 ** @release 6.4.0
4687 ** @@
4688 ******************************************************************************/
4689 
ensMapperAddIndel(EnsPMapper mapper,ajuint srcoid,ajint srcstart,ajint srcend,ajint ori,ajuint trgoid,ajint trgstart,ajint trgend)4690 AjBool ensMapperAddIndel(EnsPMapper mapper,
4691                          ajuint srcoid,
4692                          ajint srcstart,
4693                          ajint srcend,
4694                          ajint ori,
4695                          ajuint trgoid,
4696                          ajint trgstart,
4697                          ajint trgend)
4698 {
4699     AjBool result = AJFALSE;
4700 
4701     EnsPMapperpair mp = NULL;
4702 
4703     if (!mapper)
4704         return ajFalse;
4705 
4706     if (!srcoid)
4707         return ajFalse;
4708 
4709     if (!trgoid)
4710         return ajFalse;
4711 
4712     mp = ensMapperpairNewIni(srcoid, srcstart, srcend,
4713                              trgoid, trgstart, trgend,
4714                              ori, ajTrue);
4715 
4716     result = ensMapperAddMapperpair(mapper, mp);
4717 
4718     ensMapperpairDel(&mp);
4719 
4720     return result;
4721 }
4722 
4723 
4724 
4725 
4726 /* @func ensMapperAddMapperpair ***********************************************
4727 **
4728 ** Insert an Ensembl Mapper Pair into an Ensembl Mapper.
4729 **
4730 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
4731 ** @param [u] mp [EnsPMapperpair] Ensembl Mapper Pair
4732 **
4733 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4734 **
4735 ** @release 6.2.0
4736 ** @@
4737 ******************************************************************************/
4738 
ensMapperAddMapperpair(EnsPMapper mapper,EnsPMapperpair mp)4739 AjBool ensMapperAddMapperpair(EnsPMapper mapper, EnsPMapperpair mp)
4740 {
4741     ajuint *Poid = NULL;
4742 
4743     AjPList list = NULL;
4744 
4745     AjPTable table = NULL;
4746 
4747     if (ajDebugTest("ensMapperAddMapperpair"))
4748     {
4749         ajDebug("ensMapperAddMapperpair\n"
4750                 "  mapper %p\n"
4751                 "  mp %p\n",
4752                 mapper,
4753                 mp);
4754 
4755         ensMapperpairTrace(mp, 1);
4756     }
4757 
4758     if (!mapper)
4759         return ajFalse;
4760 
4761     if (!mp)
4762         return ajFalse;
4763 
4764     if (!mp->Source)
4765         ajFatal("ensMapperAddMapperpair requires a Mapper Pair with a "
4766                 "Source Mapper Unit.\n");
4767 
4768     if (!mp->Target)
4769         ajFatal("ensMapperAddMapperpair requires a Mapper Pair with a "
4770                 "Target Mapper Unit.\n");
4771 
4772     /*
4773     ** Check for matching Ensembl Mapper Unit lengths if this is not an
4774     ** Ensembl Mapper Pair reflecting an insertion or deletion.
4775     */
4776 
4777     if ((!mp->Indel) &&
4778         ((mp->Source->End - mp->Source->Start) !=
4779          (mp->Target->End - mp->Target->Start)))
4780         ajFatal("ensMapperAddMapperpair cannot deal with mis-lengthed "
4781                 "mappings so far.\n");
4782 
4783     /*
4784     ** Insert the Ensembl Mapper Pair into the source branch of the
4785     ** Ensembl Mapper.
4786     **
4787     ** Search the first-level AJAX Table of AJAX String (Ensembl Mapper type)
4788     ** objects for the second-level AJAX Table of AJAX unsigned integer
4789     ** (Ensembl identifer) objects.
4790     */
4791 
4792     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
4793                                         mapper->TypeSource);
4794 
4795     if (table)
4796     {
4797         /*
4798         ** Search the second-level AJAX Table of AJAX unsigned integer
4799         ** (Ensembl identifier) objects for the third-level
4800         ** AJAX List of Ensembl Mapper Pair objects.
4801         */
4802 
4803         list = (AjPList) ajTableFetchmodV(
4804             table,
4805             (const void *) &mp->Source->Objectidentifier);
4806 
4807         if (!list)
4808         {
4809             AJNEW0(Poid);
4810 
4811             *Poid = mp->Source->Objectidentifier;
4812 
4813             list = ajListNew();
4814 
4815             ajTablePut(table, (void *) Poid, (void *) list);
4816         }
4817 
4818         ajListPushAppend(list, (void *) ensMapperpairNewRef(mp));
4819     }
4820     else
4821         ajFatal("ensMapperAddMapperpair first-level AJAX Table for "
4822                 "Ensembl Mapper source type '%S' has not been initialised.",
4823                 mapper->TypeSource);
4824 
4825     /*
4826     ** Insert the Ensembl Mapper Pair into the target branch of the
4827     ** Ensembl Mapper.
4828     **
4829     ** Search the first-level AJAX Table of AJAX String (Ensembl Mapper type)
4830     ** objects for the second-level AJAX Table of AJAX unsigned integer
4831     ** (Ensembl identifer) objects.
4832     */
4833 
4834     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
4835                                         mapper->TypeTarget);
4836 
4837     if (table)
4838     {
4839         /*
4840         ** Search the second-level AJAX Table of AJAX unsigned integer
4841         ** (Ensembl identifier) objects for the third-level AJAX List of
4842         ** Ensembl Mapper Pair objects.
4843         */
4844 
4845         list = (AjPList) ajTableFetchmodV(
4846             table,
4847             (const void *) &mp->Target->Objectidentifier);
4848 
4849         if (!list)
4850         {
4851             AJNEW0(Poid);
4852 
4853             *Poid = mp->Target->Objectidentifier;
4854 
4855             list = ajListNew();
4856 
4857             ajTablePut(table, (void *) Poid, (void *) list);
4858         }
4859 
4860         ajListPushAppend(list, (void *) ensMapperpairNewRef(mp));
4861     }
4862     else
4863         ajFatal("ensMapperAddMapperpair first-level AJAX Table for "
4864                 "Ensembl Mapper target type '%S' has not been initialised.",
4865                 mapper->TypeTarget);
4866 
4867     mapper->Count++;
4868 
4869     mapper->Sorted = ajFalse;
4870 
4871     return ajTrue;
4872 }
4873 
4874 
4875 
4876 
4877 /* @func ensMapperAddMappers **************************************************
4878 **
4879 ** Transfer all Ensembl Mapper Pair objects from the second into the first
4880 ** Ensembl Mapper.
4881 **
4882 ** @cc Bio::EnsEMBL::Mapper::add_Mapper
4883 ** @param [u] mapper1 [EnsPMapper] First Ensembl Mapper
4884 ** @param [u] mapper2 [EnsPMapper] Second Ensembl Mapper
4885 **
4886 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4887 **
4888 ** @release 6.4.0
4889 ** @@
4890 ******************************************************************************/
4891 
ensMapperAddMappers(EnsPMapper mapper1,EnsPMapper mapper2)4892 AjBool ensMapperAddMappers(EnsPMapper mapper1, EnsPMapper mapper2)
4893 {
4894     void **keyarray = NULL;
4895     void **valarray = NULL;
4896 
4897     register ajuint i = 0U;
4898 
4899     ajuint srccounter = 0U;
4900     ajuint trgcounter = 0U;
4901 
4902     AjPList list1 = NULL;
4903     AjPList list2 = NULL;
4904 
4905     AjPTable table1 = NULL;
4906     AjPTable table2 = NULL;
4907 
4908     EnsPMapperpair mp = NULL;
4909 
4910     if (!mapper1)
4911         return ajFalse;
4912 
4913     if (!mapper2)
4914         return ajFalse;
4915 
4916     if (!ajStrMatchCaseS(mapper1->TypeSource, mapper2->TypeSource) ||
4917         !ajStrMatchCaseS(mapper1->TypeTarget, mapper2->TypeTarget))
4918         ajFatal("ensMapperAddMappers trying to add Ensembl Mapper of "
4919                 "incompatible type ('%S:%S' vs '%S:%S').",
4920                 mapper1->TypeSource,
4921                 mapper1->TypeTarget,
4922                 mapper2->TypeSource,
4923                 mapper2->TypeTarget);
4924 
4925     /*
4926     ** Get the first-level AJAX Table objects for the source type of both
4927     ** Ensembl Mapper objects.
4928     */
4929 
4930     table1 = (AjPTable) ajTableFetchmodS(mapper1->Mapperpairs,
4931                                          mapper1->TypeSource);
4932 
4933     if (!table1)
4934         ajFatal("ensMapperAddMappers first-level AJAX Table for first "
4935                 "Ensembl Mapper source type '%S' not initialised.",
4936                 mapper1->TypeSource);
4937 
4938     table2 = (AjPTable) ajTableFetchmodS(mapper2->Mapperpairs,
4939                                          mapper2->TypeSource);
4940 
4941     if (!table2)
4942         ajFatal("ensMapperAddMappers first-level AJAX Table for second "
4943                 "Ensembl Mapper source type '%S' not initialised.",
4944                 mapper2->TypeSource);
4945 
4946     /*
4947     ** Convert the second-level AJAX Table with AJAX unsigned integer
4948     ** (Ensembl identifier) objects as key data and AJAX List value data
4949     ** for the second Ensembl Mapper.
4950     */
4951 
4952     ajTableToarrayKeysValues(table2, &keyarray, &valarray);
4953 
4954     for (i = 0U; keyarray[i]; i++)
4955     {
4956         /*
4957         ** Get third-level AJAX List objects for corresponding
4958         ** AJAX unsigned integer (Ensembl identifier) objects.
4959         */
4960 
4961         list1 = (AjPList) ajTableFetchmodV(table1, (const void *) &keyarray[i]);
4962 
4963         list2 = (AjPList) valarray[i];
4964 
4965         while (ajListPop(list2, (void **) &mp))
4966         {
4967             ajListPushAppend(list1, (void *) mp);
4968 
4969             srccounter++;
4970         }
4971 
4972         /*
4973         ** Remove the entry from the AJAX Table and free the
4974         ** AJAX unsigned integer (Ensembl identifier) and the AJAX List.
4975         */
4976 
4977         ajTableRemove(table2, (const void *) keyarray[i]);
4978 
4979         AJFREE(keyarray[i]);
4980 
4981         ajListFree(&list2);
4982     }
4983 
4984     AJFREE(keyarray);
4985     AJFREE(valarray);
4986 
4987     /*
4988     ** Get the first-level AJAX Table objects for the target type of both
4989     ** Ensembl Mapper objects.
4990     */
4991 
4992     table1 = (AjPTable) ajTableFetchmodS(mapper1->Mapperpairs,
4993                                          mapper1->TypeTarget);
4994 
4995     if (!table1)
4996         ajFatal("ensMapperAddMappers first-level AJAX Table for first "
4997                 "Ensembl Mapper target type '%S' not initialised.",
4998                 mapper1->TypeTarget);
4999 
5000     table2 = (AjPTable) ajTableFetchmodS(mapper2->Mapperpairs,
5001                                          mapper2->TypeTarget);
5002 
5003     if (!table2)
5004         ajFatal("ensMapperAddMappers first-level AJAX Table for second "
5005                 "Ensembl Mapper target type '%S' not initialised.",
5006                 mapper2->TypeTarget);
5007 
5008     /*
5009     ** Convert the second-level AJAX Table with AJAX unsigned integer
5010     ** (Ensembl identifier) objects as key data and
5011     ** AJAX List value data for the second Ensembl Mapper.
5012     */
5013 
5014     ajTableToarrayKeysValues(table2, &keyarray, &valarray);
5015 
5016     for (i = 0U; keyarray[i]; i++)
5017     {
5018         /*
5019         ** Get third-level AJAX List objects for corresponding
5020         ** AJAX unsigned integer (Ensembl identifier) objects.
5021         */
5022 
5023         list1 = (AjPList) ajTableFetchmodV(table1, (const void *) &keyarray[i]);
5024 
5025         list2 = (AjPList) valarray[i];
5026 
5027         while (ajListPop(list2, (void **) &mp))
5028         {
5029             ajListPushAppend(list1, (void *) mp);
5030 
5031             trgcounter++;
5032         }
5033 
5034         /*
5035         ** Remove the entry from the AJAX Table and free the
5036         ** AJAX unsigned integer (Ensembl identifier) object and the AJAX List.
5037         */
5038 
5039         ajTableRemove(table2, (const void *) keyarray[i]);
5040 
5041         AJFREE(keyarray[i]);
5042 
5043         ajListFree(&list2);
5044     }
5045 
5046     AJFREE(keyarray);
5047     AJFREE(valarray);
5048 
5049     if (srccounter == trgcounter)
5050         mapper1->Count += srccounter;
5051     else
5052         ajFatal("ensMapperAddMappers Numbers of Ensembl Mapper Pair objects "
5053                 "for source (%u) and target (%u) types do not match in the "
5054                 "second Ensembl Mapper.",
5055                 srccounter, trgcounter);
5056 
5057     mapper1->Sorted = ajFalse;
5058 
5059     return ajTrue;
5060 }
5061 
5062 
5063 
5064 
5065 /* @func ensMapperAddMapperunits **********************************************
5066 **
5067 ** Insert Ensembl Mapper Unit objects into an Ensembl Mapper.
5068 **
5069 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
5070 ** @param [u] srcmu [EnsPMapperunit] Source Ensembl Mapper Unit
5071 ** @param [u] trgmu [EnsPMapperunit] Target Ensembl Mapper Unit
5072 ** @param [r] ori [ajint] Relative orientation of the Ensembl Mapper Unit
5073 **                        objects
5074 ** @param [r] indel [AjBool] Insertion-deletion attribute
5075 **
5076 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5077 **
5078 ** @release 6.2.0
5079 ** @@
5080 ******************************************************************************/
5081 
ensMapperAddMapperunits(EnsPMapper mapper,EnsPMapperunit srcmu,EnsPMapperunit trgmu,ajint ori,AjBool indel)5082 AjBool ensMapperAddMapperunits(EnsPMapper mapper,
5083                                EnsPMapperunit srcmu,
5084                                EnsPMapperunit trgmu,
5085                                ajint ori,
5086                                AjBool indel)
5087 {
5088     AjBool result = AJFALSE;
5089 
5090     EnsPMapperpair mp = NULL;
5091 
5092     if (!mapper)
5093         return ajFalse;
5094 
5095     if (!srcmu)
5096         return ajFalse;
5097 
5098     if (!trgmu)
5099         return ajFalse;
5100 
5101     mp = ensMapperpairNewUnit(srcmu, trgmu, ori, indel);
5102 
5103     result = ensMapperAddMapperpair(mapper, mp);
5104 
5105     ensMapperpairDel(&mp);
5106 
5107     return result;
5108 }
5109 
5110 
5111 
5112 
5113 /* @section debugging *********************************************************
5114 **
5115 ** Functions for reporting of an Ensembl Mapper object.
5116 **
5117 ** @fdata [EnsPMapper]
5118 **
5119 ** @nam3rule List List Ensembl Mapper Pair objects
5120 ** @nam3rule Trace Report Ensembl Mapper members to debug file
5121 **
5122 ** @argrule List mapper [EnsPMapper] Ensembl Mapper
5123 ** @argrule List oid [ajuint] Ensembl Object identifier
5124 ** @argrule List start [ajint] Start coordinate
5125 ** @argrule List end [ajint] End coordinate
5126 ** @argrule List type [const AjPStr] Ensembl Mapper type
5127 ** @argrule List mps [AjPList] AJAX List of Ensembl Mapper Pair objects
5128 ** @argrule Trace mapper [const EnsPMapper] Ensembl Mapper
5129 ** @argrule Trace level [ajuint] Indentation level
5130 **
5131 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
5132 **
5133 ** @fcategory misc
5134 ******************************************************************************/
5135 
5136 
5137 
5138 
5139 /* @func ensMapperList ********************************************************
5140 **
5141 ** List Ensembl Mapper Pair objects in an Ensembl Mapper.
5142 ** The caller is responsible for deleting the Ensembl Mapper Pair objects
5143 ** before deleting the AJAX List.
5144 **
5145 ** @cc Bio::EnsEMBL::Mapper::list_pairs
5146 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
5147 ** @param [r] oid [ajuint] Ensembl Object identifier
5148 ** @param [r] start [ajint] Start coordinate
5149 ** @param [r] end [ajint] End coordinate
5150 ** @param [r] type [const AjPStr] Ensembl Mapper type
5151 ** @param [u] mps [AjPList] AJAX List of Ensembl Mapper Pair objects
5152 **
5153 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5154 **
5155 ** @release 6.4.0
5156 ** @@
5157 ******************************************************************************/
5158 
ensMapperList(EnsPMapper mapper,ajuint oid,ajint start,ajint end,const AjPStr type,AjPList mps)5159 AjBool ensMapperList(EnsPMapper mapper,
5160                      ajuint oid,
5161                      ajint start,
5162                      ajint end,
5163                      const AjPStr type,
5164                      AjPList mps)
5165 {
5166     EnsEMapperunitType mutype = ensEMapperunitTypeNULL;
5167 
5168     AjPList list = NULL;
5169     AjIList iter = NULL;
5170 
5171     AjPTable table = NULL;
5172 
5173     EnsPMapperpair mp = NULL;
5174 
5175     EnsPMapperunit mu = NULL;
5176 
5177     if (!mapper)
5178         return ajFalse;
5179 
5180     if (!oid)
5181         return ajFalse;
5182 
5183     if (!type)
5184         return ajFalse;
5185 
5186     if (!mapper->Sorted)
5187         mapperMapperpairsSort(mapper);
5188 
5189     if (start > end)
5190         ajFatal("ensMapperList start (%d) is greater than end (%d) "
5191                 "for Ensembl Object identifier %u.\n",
5192                 start, end, oid);
5193 
5194     if (ajStrMatchCaseS(mapper->TypeSource, type))
5195         mutype = ensEMapperunitTypeSource;
5196     else if (ajStrMatchCaseS(mapper->TypeTarget, type))
5197         mutype = ensEMapperunitTypeTarget;
5198     else
5199         ajFatal("ensMapperList type '%S' is neither the source '%S' nor "
5200                 "target '%S' type of the Ensembl Mapper.\n",
5201                 type, mapper->TypeSource, mapper->TypeTarget);
5202 
5203     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs, type);
5204 
5205     if (!table)
5206         ajFatal("ensMapperList first-level AJAX Table for "
5207                 "Ensembl Mapper type '%S' has not been initialised.",
5208                 type);
5209 
5210     list = (AjPList) ajTableFetchmodV(table, (const void *) &oid);
5211 
5212     if (!list)
5213         return ajTrue;
5214 
5215     iter = ajListIterNew(list);
5216 
5217     while (!ajListIterDone(iter))
5218     {
5219         mp = (EnsPMapperpair) ajListIterGet(iter);
5220 
5221         if ((!start) && (!end))
5222         {
5223             ajListPushAppend(mps, (void *) ensMapperpairNewRef(mp));
5224 
5225             continue;
5226         }
5227 
5228         mu = ensMapperpairCalculateMapperunit(mp, mutype);
5229 
5230         if (mu->End < start)
5231             continue;
5232 
5233         if (mu->Start > end)
5234             break;
5235 
5236         ajListPushAppend(mps, (void *) ensMapperpairNewRef(mp));
5237     }
5238 
5239     ajListIterDel(&iter);
5240 
5241     return ajTrue;
5242 }
5243 
5244 
5245 
5246 
5247 /* @func ensMapperTrace *******************************************************
5248 **
5249 ** Trace an Ensembl Mapper.
5250 **
5251 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
5252 ** @param [r] level [ajuint] Indentation level
5253 **
5254 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5255 **
5256 ** @release 6.2.0
5257 ** @@
5258 ******************************************************************************/
5259 
ensMapperTrace(const EnsPMapper mapper,ajuint level)5260 AjBool ensMapperTrace(const EnsPMapper mapper, ajuint level)
5261 {
5262     void **keyarray = NULL;
5263     void **valarray = NULL;
5264 
5265     register ajuint i = 0U;
5266 
5267     ajuint *Poid = NULL;
5268 
5269     AjIList iter = NULL;
5270 
5271     AjPStr indent = NULL;
5272 
5273     AjPTable table = NULL;
5274 
5275     EnsPMapperpair mp = NULL;
5276 
5277     if (!mapper)
5278         return ajFalse;
5279 
5280     indent = ajStrNew();
5281 
5282     ajStrAppendCountK(&indent, ' ', level * 2);
5283 
5284     ajDebug("%SensMapperTrace %p\n"
5285             "%S  TypeSource '%S'\n"
5286             "%S  TypeTarget '%S'\n"
5287             "%S  CoordsystemSource %p\n"
5288             "%S  CoordsystemTarget %p\n"
5289             "%S  Mapperpairs %p\n"
5290             "%S  Count %u\n"
5291             "%S  Sorted '%B'\n"
5292             "%S  Use %u\n",
5293             indent, mapper,
5294             indent, mapper->TypeSource,
5295             indent, mapper->TypeTarget,
5296             indent, mapper->CoordsystemSource,
5297             indent, mapper->CoordsystemTarget,
5298             indent, mapper->Mapperpairs,
5299             indent, mapper->Count,
5300             indent, mapper->Sorted,
5301             indent, mapper->Use);
5302 
5303     ensCoordsystemTrace(mapper->CoordsystemSource, level + 1);
5304 
5305     ensCoordsystemTrace(mapper->CoordsystemTarget, level + 1);
5306 
5307     /* Trace the AJAX Table for the TypeSource. */
5308 
5309     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
5310                                         mapper->TypeSource);
5311 
5312     ajDebug("%S  AJAX Table %p for TypeSource '%S'\n",
5313             indent, table, mapper->TypeSource);
5314 
5315     ajTableToarrayKeysValues(table, &keyarray, &valarray);
5316 
5317     for (i = 0U; valarray[i]; i++)
5318     {
5319         Poid = (ajuint *) keyarray[i];
5320 
5321         ajDebug("%S    AJAX List %p for Object identifier %u\n",
5322                 indent, valarray[i], *Poid);
5323 
5324         iter = ajListIterNew((AjPList) valarray[i]);
5325 
5326         while (!ajListIterDone(iter))
5327         {
5328             mp = (EnsPMapperpair) ajListIterGet(iter);
5329 
5330             ensMapperpairTrace(mp, level + 3);
5331         }
5332 
5333         ajListIterDel(&iter);
5334     }
5335 
5336     AJFREE(keyarray);
5337     AJFREE(valarray);
5338 
5339     /* Trace the AJAX Table for the TypeTarget. */
5340 
5341     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs,
5342                                         mapper->TypeTarget);
5343 
5344     ajDebug("%S  AJAX Table %p for TypeTarget '%S'\n",
5345             indent, table, mapper->TypeTarget);
5346 
5347     ajTableToarrayKeysValues(table, &keyarray, &valarray);
5348 
5349     for (i = 0U; valarray[i]; i++)
5350     {
5351         Poid = (ajuint *) keyarray[i];
5352 
5353         ajDebug("%S    AJAX List %p for Object identifier %u\n",
5354                 indent, valarray[i], *Poid);
5355 
5356         iter = ajListIterNew((AjPList) valarray[i]);
5357 
5358         while (!ajListIterDone(iter))
5359         {
5360             mp = (EnsPMapperpair) ajListIterGet(iter);
5361 
5362             ensMapperpairTrace(mp, level + 3);
5363         }
5364 
5365         ajListIterDel(&iter);
5366     }
5367 
5368     AJFREE(keyarray);
5369     AJFREE(valarray);
5370 
5371     ajStrDel(&indent);
5372 
5373     return ajTrue;
5374 }
5375 
5376 
5377 
5378 
5379 /* @section calculate *********************************************************
5380 **
5381 ** Functions for calculating information from an Ensembl Mapper object.
5382 **
5383 ** @fdata [EnsPMapper]
5384 **
5385 ** @nam3rule Calculate Calculate Ensembl Mapper information
5386 ** @nam4rule Memsize Calculate the memory size in bytes
5387 **
5388 ** @argrule * mapper [const EnsPMapper] Ensembl Mapper
5389 **
5390 ** @valrule Memsize [size_t] Memory size in bytes or 0
5391 **
5392 ** @fcategory misc
5393 ******************************************************************************/
5394 
5395 
5396 
5397 
5398 /* @func ensMapperCalculateMemsize ********************************************
5399 **
5400 ** Calculate the memory size in bytes of an Ensembl Mapper.
5401 **
5402 ** @param [r] mapper [const EnsPMapper] Ensembl Mapper
5403 **
5404 ** @return [size_t] Memory size in bytes or 0
5405 **
5406 ** @release 6.4.0
5407 ** @@
5408 ******************************************************************************/
5409 
ensMapperCalculateMemsize(const EnsPMapper mapper)5410 size_t ensMapperCalculateMemsize(const EnsPMapper mapper)
5411 {
5412     void **keyarray1 = NULL;
5413     void **valarray1 = NULL;
5414 
5415     void **valarray2 = NULL;
5416 
5417     register ajuint i = 0U;
5418     register ajuint j = 0U;
5419 
5420     size_t size = 0;
5421 
5422     AjIList iter = NULL;
5423 
5424     EnsPMapperpair mp = NULL;
5425 
5426     if (!mapper)
5427         return 0;
5428 
5429     size += sizeof (EnsOMapper);
5430 
5431     if (mapper->TypeSource)
5432     {
5433         size += sizeof (AjOStr);
5434 
5435         size += ajStrGetRes(mapper->TypeSource);
5436     }
5437 
5438     if (mapper->TypeTarget)
5439     {
5440         size += sizeof (AjOStr);
5441 
5442         size += ajStrGetRes(mapper->TypeTarget);
5443     }
5444 
5445     size += ensCoordsystemCalculateMemsize(mapper->CoordsystemSource);
5446     size += ensCoordsystemCalculateMemsize(mapper->CoordsystemTarget);
5447 
5448     /* Level 0 data (AjOTable). */
5449 
5450     size += sizeof (AjOTable);
5451 
5452     ajTableToarrayKeysValues(mapper->Mapperpairs, &keyarray1, &valarray1);
5453 
5454     for (i = 0U; valarray1[i]; i++)
5455     {
5456         /* Level 1 key data (AjOStr). */
5457 
5458         size += sizeof (AjOStr);
5459 
5460         size += ajStrGetRes((AjPStr) keyarray1[i]);
5461 
5462         /* Level 1 value data (AjOTable). */
5463 
5464         size += sizeof (AjOTable);
5465 
5466         ajTableToarrayValues(valarray1[i], &valarray2);
5467 
5468         for (j = 0U; valarray2[j]; j++)
5469         {
5470             /* Level 2 key data (ajuint). */
5471 
5472             size += sizeof (ajuint);
5473 
5474             /* Level 2 value data (AjOList). */
5475 
5476             size += sizeof (AjOList);
5477 
5478             iter = ajListIterNew((AjPList) valarray2[j]);
5479 
5480             while (!ajListIterDone(iter))
5481             {
5482                 /* Level 3 data (EnsOMapperpair). */
5483 
5484                 mp = (EnsPMapperpair) ajListIterGet(iter);
5485 
5486                 size += ensMapperpairCalculateMemsize(mp);
5487             }
5488 
5489             ajListIterDel(&iter);
5490         }
5491 
5492         AJFREE(valarray2);
5493     }
5494 
5495     AJFREE(keyarray1);
5496     AJFREE(valarray1);
5497 
5498     return size;
5499 }
5500 
5501 
5502 
5503 
5504 /* @funcstatic mapperMapInsert ************************************************
5505 **
5506 ** Internal function to handle the special mapping case for inserts, where by
5507 ** Ensembl convention (start == end + 1). This function will be called
5508 ** automatically by the map function so there is no reason to call it directly.
5509 ** The caller is responsible for deleting the Ensembl Mapper Results before
5510 ** deleting the AJAX List.
5511 **
5512 ** @cc Bio::EnsEMBL::Mapper::map_insert
5513 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
5514 ** @param [r] oid [ajuint] Ensembl Object identifier
5515 ** @param [r] start [ajint] Start coordinate
5516 ** @param [r] end [ajint] End coordinate
5517 ** @param [r] strand [ajint] Strand information
5518 ** @param [r] type [const AjPStr] Ensembl Mapper source type
5519 ** @param [r] fastmap [AjBool] Fast-mapping attribute
5520 ** @param [u] mrs [AjPList] AJAX list of Ensembl Mapper Results
5521 **
5522 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5523 **
5524 ** @release 6.2.0
5525 ** @@
5526 ******************************************************************************/
5527 
mapperMapInsert(EnsPMapper mapper,ajuint oid,ajint start,ajint end,ajint strand,const AjPStr type,AjBool fastmap,AjPList mrs)5528 static AjBool mapperMapInsert(EnsPMapper mapper,
5529                               ajuint oid,
5530                               ajint start,
5531                               ajint end,
5532                               ajint strand,
5533                               const AjPStr type,
5534                               AjBool fastmap,
5535                               AjPList mrs)
5536 {
5537     ajint srcstart = 0;
5538     ajint srcend   = 0;
5539 
5540     AjPList coords = NULL;
5541 
5542     EnsPMapperresult mr = NULL;
5543 
5544     if (!mapper)
5545         return ajFalse;
5546 
5547     if (!oid)
5548         return ajFalse;
5549 
5550     if (ajDebugTest("mapperMapInsert"))
5551         ajDebug("mapperMapInsert\n"
5552                 "  mapper %p\n"
5553                 "  oid %u\n"
5554                 "  start %d\n"
5555                 "  end %d\n"
5556                 "  strand %d\n"
5557                 "  type '%S'\n"
5558                 "  fastmap '%B'\n"
5559                 "  mrs %p\n",
5560                 mapper,
5561                 oid,
5562                 start,
5563                 end,
5564                 strand,
5565                 type,
5566                 fastmap,
5567                 mrs);
5568 
5569     srcstart = end;
5570     srcend   = start;
5571 
5572     coords = ajListNew();
5573 
5574     ensMapperMap(mapper, oid, srcstart, srcend, strand,
5575                  type, coords);
5576 
5577     if (ajListGetLength(coords) == 1)
5578     {
5579         ajListPop(coords, (void **) &mr);
5580 
5581         /*
5582         ** Swap start and end to convert back into an insert where
5583         ** (start == end + 1)
5584         */
5585 
5586         srcstart = mr->CoordinateEnd;
5587         srcend   = mr->CoordinateStart;
5588 
5589         mr->CoordinateStart = srcstart;
5590         mr->CoordinateEnd   = srcend;
5591 
5592         ajListPushAppend(mrs, (void *) ensMapperresultNewRef(mr));
5593 
5594         ensMapperresultDel(&mr);
5595     }
5596     else
5597     {
5598         if (ajListGetLength(coords) != 2)
5599             ajFatal("mapperMapInsert got %d Ensembl Mapper Pair objects "
5600                     "but expected only two.\n",
5601                     ajListGetLength(coords));
5602 
5603         /* Adjust coordinates and remove gaps. */
5604 
5605         if (strand < 0)
5606             ajListReverse(coords);
5607 
5608         ajListPop(coords, (void **) &mr);
5609 
5610         if (mr->Type == ensEMapperresultTypeCoordinate)
5611         {
5612             /* The insert is after the first coordinate. */
5613 
5614             if ((mr->CoordinateStrand * strand) < 0)
5615                 mr->CoordinateEnd--;
5616             else
5617                 mr->CoordinateStart++;
5618 
5619             ajListPushAppend(mrs, (void *) ensMapperresultNewRef(mr));
5620         }
5621 
5622         ensMapperresultDel(&mr);
5623 
5624         ajListPop(coords, (void **) &mr);
5625 
5626         if (mr->Type == ensEMapperresultTypeCoordinate)
5627         {
5628             /* The insert is before the second coordinate. */
5629 
5630             if ((mr->CoordinateStrand * strand) < 0)
5631                 mr->CoordinateStart++;
5632             else
5633                 mr->CoordinateEnd++;
5634 
5635             if (strand < 0)
5636                 ajListPush(mrs, (void *) ensMapperresultNewRef(mr));
5637             else
5638                 ajListPushAppend(mrs, (void *) ensMapperresultNewRef(mr));
5639         }
5640 
5641         ensMapperresultDel(&mr);
5642     }
5643 
5644     if (fastmap && (ajListGetLength(mrs) != 1))
5645         while (ajListPop(mrs, (void **) &mr))
5646             ensMapperresultDel(&mr);
5647 
5648     ajListFree(&coords);
5649 
5650     return ajTrue;
5651 }
5652 
5653 
5654 
5655 
5656 /* @section map ***************************************************************
5657 **
5658 ** Map coordinates between Ensembl Coordinate System objects.
5659 **
5660 ** @fdata [EnsPMapper]
5661 **
5662 ** @nam3rule Fastmap Fast map coordinates
5663 ** @nam3rule Map Map coordinates
5664 ** @nam3rule Mapindel Map insertion-deletion coordinates
5665 **
5666 ** @argrule * mapper [EnsPMapper] Ensembl Mapper
5667 ** @argrule * oid [ajuint] Ensembl Object Identifier
5668 ** @argrule * start [ajint] Start coordinate
5669 ** @argrule * end [ajint] End coordinate
5670 ** @argrule * strand [ajint] Strand information
5671 ** @argrule * type [const AjPStr] Ensembl Mapper type to map from
5672 ** @argrule * mrs [AjPList] AJAX List of Ensembl Mapper Result objects
5673 **
5674 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
5675 **
5676 ** @fcategory use
5677 ******************************************************************************/
5678 
5679 
5680 
5681 
5682 /* @func ensMapperFastmap *****************************************************
5683 **
5684 ** Inferior mapping function, which will only perform ungapped,
5685 ** unsplit mapping. This function will return at most one Ensembl Mapper Result
5686 ** of type ensEMapperresultTypeCoordinate upon success and an empty AJAX List
5687 ** otherwise.
5688 **
5689 ** The caller is responsible for deleting the Ensembl Mapper Result objects
5690 ** before deleting the AJAX List.
5691 **
5692 ** @cc Bio::EnsEMBL::Mapper::fastmap
5693 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
5694 ** @param [r] oid [ajuint] Ensembl Object identifier
5695 ** @param [r] start [ajint] Start coordinate
5696 ** @param [r] end [ajint] End coordinate
5697 ** @param [r] strand [ajint] Strand information
5698 ** @param [r] type [const AjPStr] Ensembl Mapper type to map from
5699 ** @param [u] mrs [AjPList] AJAX List of Ensembl Mapper Results
5700 **
5701 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5702 **
5703 ** @release 6.4.0
5704 ** @@
5705 ******************************************************************************/
5706 
ensMapperFastmap(EnsPMapper mapper,ajuint oid,ajint start,ajint end,ajint strand,const AjPStr type,AjPList mrs)5707 AjBool ensMapperFastmap(EnsPMapper mapper,
5708                         ajuint oid,
5709                         ajint start,
5710                         ajint end,
5711                         ajint strand,
5712                         const AjPStr type,
5713                         AjPList mrs)
5714 {
5715     AjBool debug = AJFALSE;
5716 
5717     EnsEMapperunitType srctype = ensEMapperunitTypeNULL;
5718     EnsEMapperunitType trgtype = ensEMapperunitTypeNULL;
5719 
5720     AjIList iter = NULL;
5721     AjPList list = NULL;
5722 
5723     AjPTable table = NULL;
5724 
5725     EnsPCoordsystem cs = NULL;
5726 
5727     EnsPMapperpair mp = NULL;
5728 
5729     EnsPMapperresult mr = NULL;
5730 
5731     EnsPMapperunit srcmu = NULL;
5732     EnsPMapperunit trgmu = NULL;
5733 
5734     debug = ajDebugTest("ensMapperFastmap");
5735 
5736     if (debug)
5737         ajDebug("ensMapperFastmap\n"
5738                 "  mapper %p\n"
5739                 "  oid %u\n"
5740                 "  start %d\n"
5741                 "  end %d\n"
5742                 "  strand %d\n"
5743                 "  type '%S'\n"
5744                 "  mrs %p\n",
5745                 mapper,
5746                 oid,
5747                 start,
5748                 end,
5749                 strand,
5750                 type,
5751                 mrs);
5752 
5753     if (!mapper)
5754         return ajFalse;
5755 
5756     if (!oid)
5757         return ajFalse;
5758 
5759     if (!type)
5760         return ajFalse;
5761 
5762     if (!mrs)
5763         return ajFalse;
5764 
5765     if (start == (end + 1))
5766         return mapperMapInsert(mapper, oid, start, end, strand, type,
5767                                ajTrue, mrs);
5768 
5769     if (!mapper->Sorted)
5770         mapperMapperpairsSort(mapper);
5771 
5772     if (ajStrMatchCaseS(mapper->TypeSource, type))
5773     {
5774         srctype = ensEMapperunitTypeSource;
5775         trgtype = ensEMapperunitTypeTarget;
5776 
5777         cs = mapper->CoordsystemTarget;
5778     }
5779     else if (ajStrMatchCaseS(mapper->TypeTarget, type))
5780     {
5781         srctype = ensEMapperunitTypeTarget;
5782         trgtype = ensEMapperunitTypeSource;
5783 
5784         cs = mapper->CoordsystemSource;
5785     }
5786     else
5787         ajFatal("ensMapperFastmap type '%S' is neither the "
5788                 "source '%S' nor "
5789                 "target '%S' type of the Ensembl Mapper.\n",
5790                 type,
5791                 mapper->TypeSource,
5792                 mapper->TypeTarget);
5793 
5794     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs, type);
5795 
5796     if (!table)
5797         ajFatal("ensMapperFastmap first-level AJAX Table for "
5798                 "Ensembl Mapper type '%S' has not been initialised.\n",
5799                 type);
5800 
5801     list = (AjPList) ajTableFetchmodV(table, (const void *) &oid);
5802 
5803     if (!(list && ajListGetLength(list)))
5804     {
5805         /*
5806         ** If an Ensembl Object identifier is not associated with an
5807         ** AJAX List of Ensembl Mapper Pair objects or the AJAX List is empty,
5808         ** the whole region is just one big gap. The ensMapperFastmap
5809         ** function returns no Ensembl Mapper Result.
5810         */
5811 
5812         if (debug)
5813             ajDebug("ensMapperFastmap could not find an AJAX List for "
5814                     "Ensembl Object identifier %u or the AJAX List is empty "
5815                     "--> one big gap!\n",
5816                     oid);
5817 
5818         return ajTrue;
5819     }
5820 
5821     iter = ajListIterNew(list);
5822 
5823     while (!ajListIterDone(iter))
5824     {
5825         mp = (EnsPMapperpair) ajListIterGet(iter);
5826 
5827         srcmu = ensMapperpairCalculateMapperunit(mp, srctype);
5828         trgmu = ensMapperpairCalculateMapperunit(mp, trgtype);
5829 
5830         /* Only super easy mapping is done! */
5831 
5832         /* Continue, as long as an overlap has not been found. */
5833         if ((start < srcmu->Start) || (end > srcmu->End))
5834             continue;
5835 
5836         if (mp->Orientation >= 0)
5837             mr = ensMapperresultNewCoordinate(
5838                 trgmu->Objectidentifier,
5839                 trgmu->Start + (start - srcmu->Start),
5840                 trgmu->Start + (end   - srcmu->Start),
5841                 +strand,
5842                 cs,
5843                 0);
5844         else
5845             mr = ensMapperresultNewCoordinate(
5846                 trgmu->Objectidentifier,
5847                 trgmu->End - (end   - srcmu->Start),
5848                 trgmu->End - (start - srcmu->Start),
5849                 -strand,
5850                 cs,
5851                 0);
5852 
5853         ajListPushAppend(mrs, (void *) mr);
5854 
5855         break;
5856     }
5857 
5858     ajListIterDel(&iter);
5859 
5860     return ajTrue;
5861 }
5862 
5863 
5864 
5865 
5866 /* @func ensMapperMap *********************************************************
5867 **
5868 ** Map coordinates.
5869 **
5870 ** The caller is responsible for deleting the Ensembl Mapper Result obects
5871 ** before deleting the AJAX List.
5872 **
5873 ** @cc Bio::EnsEMBL::Mapper::map_coordinates
5874 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
5875 ** @param [r] oid [ajuint] Ensembl Object identifier
5876 ** @param [r] start [ajint] Start coordinate
5877 ** @param [r] end [ajint] End coordinate
5878 ** @param [r] strand [ajint] Strand information
5879 ** @param [r] type [const AjPStr] Ensembl Mapper type to map from
5880 ** @param [u] mrs [AjPList] AJAX List of Ensembl Mapper Results
5881 **
5882 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5883 **
5884 ** @release 6.4.0
5885 ** @@
5886 ******************************************************************************/
5887 
ensMapperMap(EnsPMapper mapper,ajuint oid,ajint start,ajint end,ajint strand,const AjPStr type,AjPList mrs)5888 AjBool ensMapperMap(EnsPMapper mapper,
5889                     ajuint oid,
5890                     ajint start,
5891                     ajint end,
5892                     ajint strand,
5893                     const AjPStr type,
5894                     AjPList mrs)
5895 {
5896     register ajuint i = 0U;
5897 
5898     ajuint idxstart  = 0U;
5899     ajuint idxmid    = 0U;
5900     ajuint idxend    = 0U;
5901     ajuint idxlength = 0U;
5902     ajuint rank      = 0U;
5903 
5904     ajint srcstart = 0;
5905     ajint srcend   = 0;
5906 
5907     ajuint trgoid  = 0U;
5908     ajint trgstart = 0;
5909     ajint trgend   = 0;
5910 
5911     AjBool debug = AJFALSE;
5912 
5913     EnsEMapperunitType srctype = ensEMapperunitTypeNULL;
5914     EnsEMapperunitType trgtype = ensEMapperunitTypeNULL;
5915 
5916     AjPList list = NULL;
5917 
5918     AjPTable table = NULL;
5919 
5920     EnsPCoordsystem cs = NULL;
5921 
5922     EnsPMapperpair mp     = NULL;
5923     EnsPMapperpair lastmp = NULL;
5924 
5925     EnsPMapperresult mr = NULL;
5926 
5927     EnsPMapperunit srcmu = NULL;
5928     EnsPMapperunit trgmu = NULL;
5929 
5930     debug = ajDebugTest("ensMapperMap");
5931 
5932     if (debug)
5933         ajDebug("ensMapperMap\n"
5934                 "  mapper %p\n"
5935                 "  oid %u\n"
5936                 "  start %d\n"
5937                 "  end %d\n"
5938                 "  strand %d\n"
5939                 "  type '%S'\n"
5940                 "  mrs %p\n",
5941                 mapper,
5942                 oid,
5943                 start,
5944                 end,
5945                 strand,
5946                 type,
5947                 mrs);
5948 
5949     if (!mapper)
5950         return ajFalse;
5951 
5952     if (!oid)
5953         return ajFalse;
5954 
5955     if (!type)
5956         return ajFalse;
5957 
5958     if (!mrs)
5959         return ajFalse;
5960 
5961     if (start == (end + 1))
5962         return mapperMapInsert(mapper, oid, start, end, strand, type,
5963                                ajFalse, mrs);
5964 
5965     if (!mapper->Sorted)
5966         mapperMapperpairsSort(mapper);
5967 
5968     if (ajStrMatchCaseS(mapper->TypeSource, type))
5969     {
5970         srctype = ensEMapperunitTypeSource;
5971         trgtype = ensEMapperunitTypeTarget;
5972 
5973         cs = mapper->CoordsystemTarget;
5974     }
5975     else if (ajStrMatchCaseS(mapper->TypeTarget, type))
5976     {
5977         srctype = ensEMapperunitTypeTarget;
5978         trgtype = ensEMapperunitTypeSource;
5979 
5980         cs = mapper->CoordsystemSource;
5981     }
5982     else
5983         ajFatal("ensMapperMap type '%S' is neither the "
5984                 "source '%S' nor "
5985                 "target '%S' type of the Ensembl Mapper.\n",
5986                 type,
5987                 mapper->TypeSource,
5988                 mapper->TypeTarget);
5989 
5990     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs, type);
5991 
5992     if (!table)
5993         ajFatal("ensMapperMap first-level AJAX Table for "
5994                 "Ensembl Mapper type '%S' has not been initialised.\n",
5995                 type);
5996 
5997     list = (AjPList) ajTableFetchmodV(table, (const void *) &oid);
5998 
5999     if (!(list && (idxlength = (ajuint) ajListGetLength(list))))
6000     {
6001         /*
6002         ** If an Ensembl Object identifier is not associated with an
6003         ** AJAX List of Ensembl Mapper Pair objects or the AJAX List is empty,
6004         ** the whole region is just one big gap.
6005         */
6006 
6007         if (debug)
6008             ajDebug("ensMapperMap could not find an AJAX List for "
6009                     "Ensembl Object identifier %u or the List is empty "
6010                     "--> one big gap!\n",
6011                     oid);
6012 
6013         mr = ensMapperresultNewGap(start, end, 0);
6014 
6015         ajListPushAppend(mrs, (void *) mr);
6016 
6017         return ajTrue;
6018     }
6019 
6020     /*
6021     ** Binary search the relevant Ensembl Mapper Pair objects,
6022     ** which helps if the AJAX List of Ensembl Mapper Pair objects is long.
6023     */
6024 
6025     idxstart = 0U;
6026     idxend   = idxlength - 1U;
6027 
6028     while ((idxend - idxstart) > 1)
6029     {
6030         idxmid = (idxstart + idxend) >> 1;
6031 
6032         ajListPeekNumber(list, idxmid, (void **) &mp);
6033 
6034         srcmu = ensMapperpairCalculateMapperunit(mp, srctype);
6035 
6036         if (srcmu->End < start)
6037             idxstart = idxmid;
6038         else
6039             idxend = idxmid;
6040     }
6041 
6042     srcstart = start;
6043     srcend   = end;
6044 
6045     for (i = idxstart; i < idxlength; i++)
6046     {
6047         ajListPeekNumber(list, i, (void **) &mp);
6048 
6049         srcmu = ensMapperpairCalculateMapperunit(mp, srctype);
6050         trgmu = ensMapperpairCalculateMapperunit(mp, trgtype);
6051 
6052         if (debug)
6053             ajDebug("ensMapperMap coordinates "
6054                     "%u:%d:%d:%d %d:%d srcMU %u:%d:%d\n",
6055                     oid,
6056                     start,
6057                     end,
6058                     strand,
6059                     srcstart,
6060                     srcend,
6061                     srcmu->Objectidentifier,
6062                     srcmu->Start,
6063                     srcmu->End);
6064 
6065         /*
6066         ** NOTE: This breaks the haplotype projection and was therefore removed
6067         ** in CVS revision 1.49
6068         **
6069         if (srcmu->Start < start)
6070         {
6071         srcstart = start;
6072 
6073         rank++;
6074         }
6075         */
6076 
6077         /*
6078         ** Check for cases where the source Mapper Unit maps to more than one
6079         ** location.
6080         ** If the target object identifier changes, and the source start
6081         ** coordinate is less than the current start coordinate, this source
6082         ** Mapper Unit maps to more than one location on a target Mapper Unit.
6083         ** Reset the current source start position to the original start.
6084         */
6085 
6086         if (trgoid && (trgoid != trgmu->Objectidentifier))
6087         {
6088             if (srcmu->Start < start)
6089                 srcstart = start;
6090         }
6091         else
6092             trgoid = trgmu->Objectidentifier;
6093 
6094         /*
6095         ** In case the Ensembl Mapper Unit loop has not even reached the start,
6096         ** move on.
6097         */
6098 
6099         if (srcmu->End < start)
6100             continue;
6101 
6102         /* In case the Ensembl Mapper Unit loop has over-run, break. */
6103 
6104         if (srcmu->Start > srcend)
6105             break;
6106 
6107         if (srcmu->Start > srcstart)
6108         {
6109             /* A gap has been detected. */
6110 
6111             mr = ensMapperresultNewGap(srcstart, srcmu->Start - 1, rank);
6112 
6113             ajListPushAppend(mrs, (void *) mr);
6114 
6115             srcstart = srcmu->Start;
6116         }
6117 
6118         if (mp->Indel)
6119         {
6120             /*
6121             ** If the Mapper Pair represents an insertion or deletion,
6122             ** create a Mapper Result of type insertion or deletion.
6123             */
6124 
6125             mr = ensMapperresultNewIndel(trgmu->Objectidentifier,
6126                                          trgmu->Start,
6127                                          trgmu->End,
6128                                          mp->Orientation * strand,
6129                                          cs,
6130                                          srcstart,
6131                                          (srcmu->End < srcend) ?
6132                                          srcmu->End : srcend,
6133                                          rank);
6134         }
6135         else
6136         {
6137             /* The start is somewhere inside the region. */
6138 
6139             if (mp->Orientation >= 0)
6140                 trgstart = trgmu->Start + (srcstart - srcmu->Start);
6141             else
6142                 trgend   = trgmu->End   - (srcstart - srcmu->Start);
6143 
6144             /*
6145             ** Either we are enveloping this map or not. If yes, then the end
6146             ** point (self perspective) is determined solely by target.
6147             ** If not we need to adjust.
6148             */
6149 
6150             if (srcend > srcmu->End)
6151             {
6152                 /*
6153                 ** Enveloped, i.e. the source Ensembl Mapper Unit is
6154                 ** contained within the end coordinate.
6155                 */
6156 
6157                 if (mp->Orientation >= 0)
6158                     trgend = trgmu->End;
6159                 else
6160                     trgstart = trgmu->Start;
6161             }
6162             else
6163             {
6164                 /*
6165                 ** The end needs to be adjusted, i.e. it is somehwere within
6166                 ** the source Ensembl Mapper Unit.
6167                 */
6168 
6169                 if (mp->Orientation >= 0)
6170                     trgend   = trgmu->Start + (srcend - srcmu->Start);
6171                 else
6172                     trgstart = trgmu->End   - (srcend - srcmu->Start);
6173             }
6174 
6175             mr = ensMapperresultNewCoordinate(trgmu->Objectidentifier,
6176                                               trgstart,
6177                                               trgend,
6178                                               mp->Orientation * strand,
6179                                               cs,
6180                                               rank);
6181         }
6182 
6183         ajListPushAppend(mrs, (void *) mr);
6184 
6185         lastmp = mp;
6186 
6187         srcstart = srcmu->End + 1;
6188     }
6189 
6190     if (lastmp)
6191     {
6192         /*
6193         ** Previously, an Ensembl Mapper Pair has been found,
6194         ** check for a gap inbetween.
6195         */
6196 
6197         srcmu = ensMapperpairCalculateMapperunit(lastmp, srctype);
6198 
6199         if (srcmu->End < srcend)
6200         {
6201             /* A gap at the end has been detected. */
6202 
6203             mr = ensMapperresultNewGap(srcmu->End + 1, srcend, rank);
6204 
6205             ajListPushAppend(mrs, (void *) mr);
6206         }
6207     }
6208     else
6209     {
6210         /*
6211         ** Since an Ensembl Mapper Pair has not been found,
6212         ** the entire region is just one gap.
6213         */
6214 
6215         mr = ensMapperresultNewGap(srcstart, srcend, 0);
6216 
6217         ajListPushAppend(mrs, (void *) mr);
6218     }
6219 
6220     if (strand < 0)
6221         ajListReverse(mrs);
6222 
6223     return ajTrue;
6224 }
6225 
6226 
6227 
6228 
6229 /* @func ensMapperMapindel ****************************************************
6230 **
6231 ** Map insertion-deletion coordinates.
6232 **
6233 ** The caller is responsible for deleting the Ensembl Mapper Result objects
6234 ** before deleting the AJAX List.
6235 **
6236 ** @cc Bio::EnsEMBL::Mapper::map_indel
6237 ** @param [u] mapper [EnsPMapper] Ensembl Mapper
6238 ** @param [r] oid [ajuint] Ensembl Object identifier
6239 ** @param [r] start [ajint] Start coordinate
6240 ** @param [r] end [ajint] End coordinate
6241 ** @param [r] strand [ajint] Strand information
6242 ** @param [r] type [const AjPStr] Ensembl Mapper type to map from
6243 ** @param [u] mrs [AjPList] AJAX List of Ensembl Mapper Results
6244 **
6245 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6246 **
6247 ** @release 6.4.0
6248 ** @@
6249 ******************************************************************************/
6250 
ensMapperMapindel(EnsPMapper mapper,ajuint oid,ajint start,ajint end,ajint strand,const AjPStr type,AjPList mrs)6251 AjBool ensMapperMapindel(EnsPMapper mapper,
6252                          ajuint oid,
6253                          ajint start,
6254                          ajint end,
6255                          ajint strand,
6256                          const AjPStr type,
6257                          AjPList mrs)
6258 {
6259     register ajuint i = 0U;
6260 
6261     ajuint idxstart  = 0U;
6262     ajuint idxend    = 0U;
6263     ajuint idxmid    = 0U;
6264     ajuint idxlength = 0U;
6265 
6266     AjBool debug = AJFALSE;
6267 
6268     EnsEMapperunitType srctype = ensEMapperunitTypeNULL;
6269     EnsEMapperunitType trgtype = ensEMapperunitTypeNULL;
6270 
6271     AjPList list = NULL;
6272 
6273     AjPTable table = NULL;
6274 
6275     EnsPCoordsystem cs = NULL;
6276 
6277     EnsPMapperpair mp = NULL;
6278 
6279     EnsPMapperresult mr = NULL;
6280 
6281     EnsPMapperunit srcmu = NULL;
6282     EnsPMapperunit trgmu = NULL;
6283 
6284     debug = ajDebugTest("ensMapperMapindel");
6285 
6286     if (debug)
6287         ajDebug("ensMapperMapindel\n"
6288                 "  mapper %p\n"
6289                 "  oid %u\n"
6290                 "  start %u\n"
6291                 "  end %u\n"
6292                 "  strand %d\n"
6293                 "  type '%S'"
6294                 "  mrs %p\n",
6295                 mapper,
6296                 oid,
6297                 start,
6298                 end,
6299                 strand,
6300                 type,
6301                 mrs);
6302 
6303     if (!mapper)
6304         return ajFalse;
6305 
6306     if (!oid)
6307         return ajFalse;
6308 
6309     if (!type)
6310         return ajFalse;
6311 
6312     if (!mrs)
6313         return ajFalse;
6314 
6315     if (!mapper->Sorted)
6316         mapperMapperpairsSort(mapper);
6317 
6318     if (ajStrMatchCaseS(mapper->TypeSource, type))
6319     {
6320         srctype = ensEMapperunitTypeSource;
6321         trgtype = ensEMapperunitTypeTarget;
6322 
6323         cs = mapper->CoordsystemTarget;
6324     }
6325     else if (ajStrMatchCaseS(mapper->TypeTarget, type))
6326     {
6327         srctype = ensEMapperunitTypeTarget;
6328         trgtype = ensEMapperunitTypeSource;
6329 
6330         cs = mapper->CoordsystemSource;
6331     }
6332     else
6333         ajFatal("ensMapperMapindel type '%S' is neither the "
6334                 "source '%S' nor "
6335                 "target '%S' type of the Ensembl Mapper.\n",
6336                 type,
6337                 mapper->TypeSource,
6338                 mapper->TypeTarget);
6339 
6340     table = (AjPTable) ajTableFetchmodS(mapper->Mapperpairs, type);
6341 
6342     if (!table)
6343         ajFatal("ensMapperMapindel first-level AJAX Table for "
6344                 "Ensembl Mapper type '%S' has not been initialised.",
6345                 type);
6346 
6347     list = (AjPList) ajTableFetchmodV(table, (const void *) &oid);
6348 
6349     if (!(list && (idxlength = (ajuint) ajListGetLength(list))))
6350     {
6351         /*
6352         ** If an Ensembl Object identifier is not associated with an
6353         ** AJAX List of Ensembl Mapper Pair objects or the AJAX List is empty,
6354         ** the whole region is just one big gap.
6355         */
6356 
6357         if (debug)
6358             ajDebug("ensMapperMapindel could not find an AJAX List for "
6359                     "Ensembl Object identifier %u or the List is empty\n",
6360                     oid);
6361 
6362         return ajTrue;
6363     }
6364 
6365     /*
6366     ** Binary search the relevant Ensembl Mapper Pair objects,
6367     ** which helps if the AJAX List of Ensembl Mapper Pair objects is long.
6368     */
6369 
6370     idxstart = 0U;
6371     idxend   = idxlength - 1U;
6372 
6373     while ((idxend - idxstart) > 1)
6374     {
6375         idxmid = (idxstart + idxend) >> 1;
6376 
6377         ajListPeekNumber(list, idxmid, (void **) &mp);
6378 
6379         srcmu = ensMapperpairCalculateMapperunit(mp, srctype);
6380 
6381         /*
6382         ** NOTE: The ensMapperMap function checks for source
6383         ** Mapper Unit end less than start. if (srcmu->End < start)
6384         ** This function has already swapped the start and end coordinates
6385         ** for the insertion-deletion and checks for source Mapper Unit end
6386         ** less than *or equal* the start. Since the coordinates have not
6387         ** been swapped here, this becomes if (srcmu->End <= end)
6388         */
6389 
6390         if (srcmu->End <= end)
6391             idxstart = idxmid;
6392         else
6393             idxend = idxmid;
6394     }
6395 
6396     for (i = idxstart; i < idxlength; i++)
6397     {
6398         ajListPeekNumber(list, i, (void **) &mp);
6399 
6400         trgmu = ensMapperpairCalculateMapperunit(mp, trgtype);
6401 
6402         if (mp->Indel)
6403         {
6404             mr = ensMapperresultNewCoordinate(trgmu->Objectidentifier,
6405                                               trgmu->Start,
6406                                               trgmu->End,
6407                                               mp->Orientation * strand,
6408                                               cs,
6409                                               0);
6410 
6411             ajListPushAppend(mrs, (void *) mr);
6412 
6413             break;
6414         }
6415     }
6416 
6417     return ajTrue;
6418 }
6419