1 /* @source ensfeature *********************************************************
2 **
3 ** Ensembl Feature functions
4 **
5 ** @author Copyright (C) 1999 Ensembl Developers
6 ** @author Copyright (C) 2006 Michael K. Schuster
7 ** @version $Revision: 1.74 $
8 ** @modified 2009 by Alan Bleasby for incorporation into EMBOSS core
9 ** @modified $Date: 2013/02/17 13:05:33 $ 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 "ensexternaldatabase.h"
34 #include "ensfeature.h"
35 #include "ensmetacoordinate.h"
36 #include "ensmetainformation.h"
37 #include "ensprojectionsegment.h"
38 #include "enstable.h"
39 
40 
41 
42 
43 /* ========================================================================= */
44 /* =============================== constants =============================== */
45 /* ========================================================================= */
46 
47 
48 
49 
50 /* ========================================================================= */
51 /* =========================== global variables ============================ */
52 /* ========================================================================= */
53 
54 
55 
56 
57 /* ========================================================================= */
58 /* ============================= private data ============================== */
59 /* ========================================================================= */
60 
61 
62 
63 
64 /* ========================================================================= */
65 /* =========================== private constants =========================== */
66 /* ========================================================================= */
67 
68 /* @conststatic featureadaptorKMaxSplitQuerySeqregions ************************
69 **
70 ** Maximum number of Ensembl Mapper Result objects for which multiple regional
71 ** constraints for Ensembl Feature objects on Ensembl Sequence Region objects
72 ** are used. Above this number of regions, it is faster to limit by
73 ** start and end coordinates.
74 **
75 ******************************************************************************/
76 
77 static const ajuint featureadaptorKMaxSplitQuerySeqregions = 3U;
78 
79 
80 
81 
82 /* @conststatic featureadaptorKCacheMaxBytes **********************************
83 **
84 ** Maximum memory size in bytes the Ensembl Feature Adaptor-internal
85 ** Ensembl Cache can use.
86 **
87 ** 1 << 26 = 64 Mi
88 **
89 ******************************************************************************/
90 
91 static const size_t featureadaptorKCacheMaxBytes = 1U << 26U;
92 
93 
94 
95 
96 /* @conststatic featureadaptorKCacheMaxCount **********************************
97 **
98 ** Maximum number of objects based on the Ensembl Feature class the
99 ** Ensembl Feature Adaptor-internal Ensembl Cache can hold.
100 **
101 ** 1 << 16 = 64 ki
102 **
103 ******************************************************************************/
104 
105 static const ajuint featureadaptorKCacheMaxCount = 1U << 16U;
106 
107 
108 
109 
110 /* @conststatic featureadaptorKCacheMaxSize ***********************************
111 **
112 ** Maximum memory size in bytes of an object based on the Ensembl Feature class
113 ** to be allowed into the Ensembl Feature Adaptor-internal Ensembl Cache.
114 **
115 ******************************************************************************/
116 
117 static const size_t featureadaptorKCacheMaxSize = 0U;
118 
119 
120 
121 
122 /* @conststatic assemblyexceptionfeatureadaptorKCacheMaxBytes *****************
123 **
124 ** Maximum memory size in bytes the Ensembl Assembly Exception Adaptor-internal
125 ** Ensembl Cache can use.
126 **
127 ** 1 << 26 = 64 Mi
128 **
129 ******************************************************************************/
130 
131 static const size_t assemblyexceptionfeatureadaptorKCacheMaxBytes = 1U << 26U;
132 
133 
134 
135 
136 /* @conststatic assemblyexceptionfeatureadaptorKCacheMaxCount *****************
137 **
138 ** Maximum number of Ensembl Assembly Exception Feature objects the
139 ** Ensembl Assembly Exception Feature Adaptor-internal Ensembl Cache can hold.
140 **
141 ** 1 << 16 = 64 ki
142 **
143 ******************************************************************************/
144 
145 static const ajuint assemblyexceptionfeatureadaptorKCacheMaxCount = 1U << 16U;
146 
147 
148 
149 
150 /* @conststatic assemblyexceptionfeatureadaptorKCacheMaxSize ******************
151 **
152 ** Maximum memory size in bytes of an Ensembl Assembly Exception Feature to be
153 ** allowed into the Ensembl Assembly Exception Feature Adaptor-internal
154 ** Ensembl Cache.
155 **
156 ******************************************************************************/
157 
158 static const size_t assemblyexceptionfeatureadaptorKCacheMaxSize = 0U;
159 
160 
161 
162 
163 /* ========================================================================= */
164 /* =========================== private variables =========================== */
165 /* ========================================================================= */
166 
167 
168 
169 
170 /* ========================================================================= */
171 /* =========================== private functions =========================== */
172 /* ========================================================================= */
173 
174 static int listFeatureCompareEndAscending(
175     const void *item1,
176     const void *item2);
177 
178 static int listFeatureCompareEndDescending(
179     const void *item1,
180     const void *item2);
181 
182 static int listFeatureCompareStartAscending(
183     const void *item1,
184     const void *item2);
185 
186 static int listFeatureCompareStartDescending(
187     const void *item1,
188     const void *item2);
189 
190 static AjBool featureadaptorRemap(EnsPFeatureadaptor fa,
191                                   AjPList objects,
192                                   EnsPAssemblymapper am,
193                                   EnsPSlice slice);
194 
195 static AjBool featureadaptorSliceFetch(EnsPFeatureadaptor fa,
196                                        EnsPSlice slice,
197                                        AjPStr constraint,
198                                        AjPList objects);
199 
200 static int listFeaturepairCompareSourceEndAscending(
201     const void *item1,
202     const void *item2);
203 
204 static int listFeaturepairCompareSourceEndDescending(
205     const void *item1,
206     const void *item2);
207 
208 static int listFeaturepairCompareSourceStartAscending(
209     const void *item1,
210     const void *item2);
211 
212 static int listFeaturepairCompareSourceStartDescending(
213     const void *item1,
214     const void *item2);
215 
216 static AjBool assemblyexceptionfeatureadaptorCacheInit(
217     EnsPAssemblyexceptionfeatureadaptor aefa);
218 
219 static AjBool assemblyexceptionfeatureadaptorRemap(
220     EnsPAssemblyexceptionfeatureadaptor aefa,
221     AjPList aefs,
222     EnsPAssemblymapper am,
223     EnsPSlice slice);
224 
225 
226 
227 
228 /* ========================================================================= */
229 /* ======================= All functions by section ======================== */
230 /* ========================================================================= */
231 
232 
233 
234 
235 /* @filesection ensfeature ****************************************************
236 **
237 ** @nam1rule ens Function belongs to the Ensembl library
238 **
239 ******************************************************************************/
240 
241 
242 
243 
244 /* @datasection [EnsPFeature] Ensembl Feature *********************************
245 **
246 ** @nam2rule Feature Functions for manipulating Ensembl Feature objects
247 **
248 ** @cc Bio::EnsEMBL::Feature
249 ** @cc CVS Revision: 1.70
250 ** @cc CVS Tag: branch-ensembl-68
251 **
252 ******************************************************************************/
253 
254 
255 
256 
257 /* @section constructors ******************************************************
258 **
259 ** All constructors return a new Ensembl Feature by pointer.
260 ** It is the responsibility of the user to first destroy any previous
261 ** Feature. The target pointer does not need to be initialised to
262 ** NULL, but it is good programming practice to do so anyway.
263 **
264 ** @fdata [EnsPFeature]
265 **
266 ** @nam3rule New Constructor
267 ** @nam4rule Cpy Constructor with existing object
268 ** @nam4rule Ini Constructor with initial values
269 ** @suffix N Constructor with a sequence name
270 ** @suffix S Constructor with an Ensembl Slice
271 ** @nam4rule Ref Constructor by incrementing the reference counter
272 **
273 ** @argrule Cpy feature [const EnsPFeature] Ensembl Feature
274 ** @argrule IniN analysis [EnsPAnalysis] Ensembl Analysis
275 ** @argrule IniN seqname [AjPStr] Sequence name
276 ** @argrule IniN start [ajint] Start coordinate
277 ** @argrule IniN end [ajint] End coordinate
278 ** @argrule IniN strand [ajint] Strand orientation
279 ** @argrule IniS analysis [EnsPAnalysis] Ensembl Analysis
280 ** @argrule IniS slice [EnsPSlice] Ensembl Slice
281 ** @argrule IniS start [ajint] Start coordinate
282 ** @argrule IniS end [ajint] End coordinate
283 ** @argrule IniS strand [ajint] Strand orientation
284 ** @argrule Ref feature [EnsPFeature] Ensembl Feature
285 **
286 ** @valrule * [EnsPFeature] Ensembl Feature or NULL
287 **
288 ** @fcategory new
289 ******************************************************************************/
290 
291 
292 
293 
294 /* @func ensFeatureNewCpy *****************************************************
295 **
296 ** Object-based constructor function, which returns an independent object.
297 **
298 ** @param [r] feature [const EnsPFeature] Ensembl Feature
299 **
300 ** @return [EnsPFeature] Ensembl Feature or NULL
301 **
302 ** @release 6.4.0
303 ** @@
304 ******************************************************************************/
305 
ensFeatureNewCpy(const EnsPFeature feature)306 EnsPFeature ensFeatureNewCpy(const EnsPFeature feature)
307 {
308     EnsPFeature pthis = NULL;
309 
310     if (!feature)
311         return NULL;
312 
313     AJNEW0(pthis);
314 
315     pthis->Analysis = ensAnalysisNewRef(feature->Analysis);
316     pthis->Slice    = ensSliceNewRef(feature->Slice);
317 
318     if (feature->Sequencename)
319         pthis->Sequencename = ajStrNewRef(feature->Sequencename);
320 
321     pthis->Start  = feature->Start;
322     pthis->End    = feature->End;
323     pthis->Strand = feature->Strand;
324     pthis->Use    = 1U;
325 
326     return pthis;
327 }
328 
329 
330 
331 
332 /* @func ensFeatureNewIniN ****************************************************
333 **
334 ** Constructor for an Ensembl Feature with a sequence name.
335 **
336 ** This is useful for Ensembl Feature objects that are not annotated on a
337 ** (genome sequence) Ensembl Slice, such as Ensembl Protein Feature objects.
338 **
339 ** @cc Bio::EnsEMBL::Feature::new
340 ** @param [u] analysis [EnsPAnalysis] Ensembl Analysis
341 ** @param [u] seqname [AjPStr] Sequence name
342 ** @param [r] start [ajint] Start coordinate
343 ** @param [r] end [ajint] End coordinate
344 ** @param [r] strand [ajint] Strand orientation
345 **
346 ** @return [EnsPFeature] Ensembl Feature or NULL
347 **
348 ** @release 6.4.0
349 ** @@
350 ******************************************************************************/
351 
ensFeatureNewIniN(EnsPAnalysis analysis,AjPStr seqname,ajint start,ajint end,ajint strand)352 EnsPFeature ensFeatureNewIniN(EnsPAnalysis analysis,
353                               AjPStr seqname,
354                               ajint start,
355                               ajint end,
356                               ajint strand)
357 {
358     EnsPFeature feature = NULL;
359 
360     if (!seqname)
361     {
362         ajDebug("ensFeatureNewIniN requires a sequence name.\n");
363 
364         return NULL;
365     }
366 
367     if (start && end && (start > (end + 1)))
368     {
369         ajDebug("ensFeatureNewIniN start (%d) must be less than or equal to "
370                 "end (%d) + 1.\n", start, end);
371 
372         return NULL;
373     }
374 
375     if ((strand < -1) || (strand > 1))
376     {
377         ajDebug("ensFeatureNewIniN strand (%d) must be +1, 0 or -1.\n",
378                 strand);
379 
380         return NULL;
381     }
382 
383     AJNEW0(feature);
384 
385     feature->Analysis = ensAnalysisNewRef(analysis);
386 
387     feature->Slice = NULL;
388 
389     if (seqname)
390         feature->Sequencename = ajStrNewRef(seqname);
391 
392     feature->Start  = start;
393     feature->End    = end;
394     feature->Strand = strand;
395     feature->Use    = 1U;
396 
397     return feature;
398 }
399 
400 
401 
402 
403 /* @func ensFeatureNewIniS ****************************************************
404 **
405 ** Constructor for an Ensembl Feature with an Ensembl Slice.
406 **
407 ** @cc Bio::EnsEMBL::Feature::new
408 ** @param [u] analysis [EnsPAnalysis] Ensembl Analysis
409 ** @param [u] slice [EnsPSlice] Ensembl Slice
410 ** @param [r] start [ajint] Start coordinate
411 ** @param [r] end [ajint] End coordinate
412 ** @param [r] strand [ajint] Strand orientation
413 **
414 ** @return [EnsPFeature] Ensembl Feature or NULL
415 **
416 ** @release 6.4.0
417 ** @@
418 ******************************************************************************/
419 
ensFeatureNewIniS(EnsPAnalysis analysis,EnsPSlice slice,ajint start,ajint end,ajint strand)420 EnsPFeature ensFeatureNewIniS(EnsPAnalysis analysis,
421                               EnsPSlice slice,
422                               ajint start,
423                               ajint end,
424                               ajint strand)
425 {
426     EnsPFeature feature = NULL;
427 
428     if (!slice)
429     {
430         ajDebug("ensFeatureNewIniS reqires an Ensembl Slice.\n");
431 
432         return NULL;
433     }
434 
435     if (start && end && (start > (end + 1)))
436     {
437         ajDebug("ensFeatureNewIniS start (%d) must be less than or equal to "
438                 "end (%d) + 1.\n", start, end);
439 
440         return NULL;
441     }
442 
443     if ((strand < -1) || (strand > 1))
444     {
445         ajDebug("ensFeatureNewIniS strand (%d) must be +1, 0 or -1.\n",
446                 strand);
447 
448         return NULL;
449     }
450 
451     AJNEW0(feature);
452 
453     feature->Analysis     = ensAnalysisNewRef(analysis);
454     feature->Slice        = ensSliceNewRef(slice);
455     feature->Sequencename = NULL;
456     feature->Start        = start;
457     feature->End          = end;
458     feature->Strand       = strand;
459     feature->Use          = 1U;
460 
461     return feature;
462 }
463 
464 
465 
466 
467 /* @func ensFeatureNewRef *****************************************************
468 **
469 ** Ensembl Object referencing function, which returns a pointer to the
470 ** Ensembl Object passed in and increases its reference count.
471 **
472 ** @param [u] feature [EnsPFeature] Ensembl Feature
473 **
474 ** @return [EnsPFeature] Ensembl Feature or NULL
475 **
476 ** @release 6.2.0
477 ** @@
478 ******************************************************************************/
479 
ensFeatureNewRef(EnsPFeature feature)480 EnsPFeature ensFeatureNewRef(EnsPFeature feature)
481 {
482     if (!feature)
483         return NULL;
484 
485     feature->Use++;
486 
487     return feature;
488 }
489 
490 
491 
492 
493 /* @section destructors *******************************************************
494 **
495 ** Destruction destroys all internal data structures and frees the memory
496 ** allocated for an Ensembl Feature object.
497 **
498 ** @fdata [EnsPFeature]
499 **
500 ** @nam3rule Del Destroy (free) an Ensembl Feature
501 **
502 ** @argrule * Pfeature [EnsPFeature*] Ensembl Feature address
503 **
504 ** @valrule * [void]
505 **
506 ** @fcategory delete
507 ******************************************************************************/
508 
509 
510 
511 
512 /* @func ensFeatureDel ********************************************************
513 **
514 ** Default destructor for an Ensembl Feature.
515 **
516 ** @param [d] Pfeature [EnsPFeature*] Ensembl Feature address
517 **
518 ** @return [void]
519 **
520 ** @release 6.2.0
521 ** @@
522 ******************************************************************************/
523 
ensFeatureDel(EnsPFeature * Pfeature)524 void ensFeatureDel(EnsPFeature *Pfeature)
525 {
526     EnsPFeature pthis = NULL;
527 
528     if (!Pfeature)
529         return;
530 
531 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
532     if (ajDebugTest("ensFeatureDel"))
533     {
534         ajDebug("ensFeatureDel\n"
535                 "  *Pfeature %p\n",
536                 *Pfeature);
537 
538         ensFeatureTrace(*Pfeature, 1);
539     }
540 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
541 
542     if (!(pthis = *Pfeature) || --pthis->Use)
543     {
544         *Pfeature = NULL;
545 
546         return;
547     }
548 
549     ensAnalysisDel(&pthis->Analysis);
550 
551     ensSliceDel(&pthis->Slice);
552 
553     ajStrDel(&pthis->Sequencename);
554 
555     ajMemFree((void **) Pfeature);
556 
557     return;
558 }
559 
560 
561 
562 
563 /* @section member retrieval **************************************************
564 **
565 ** Functions for returning members of an Ensembl Feature object.
566 **
567 ** @fdata [EnsPFeature]
568 **
569 ** @nam3rule Get Return Feature attribute(s)
570 ** @nam4rule Analysis Return the Ensembl Analysis
571 ** @nam4rule End Return the end
572 ** @nam4rule Sequencename Return the sequence name
573 ** @nam4rule Slice Return the Ensembl Slice
574 ** @nam4rule Start Return the start
575 ** @nam4rule Strand Return the strand
576 **
577 ** @argrule * feature [const EnsPFeature] Feature
578 **
579 ** @valrule Analysis [EnsPAnalysis] Ensembl Analysis or NULL
580 ** @valrule End [ajint] End or 0
581 ** @valrule Sequencename [AjPStr] Sequence name or NULL
582 ** @valrule Slice [EnsPSlice] Ensembl Slice or NULL
583 ** @valrule Start [ajint] Start or 0
584 ** @valrule Strand [ajint] Strand or 0
585 **
586 ** @fcategory use
587 ******************************************************************************/
588 
589 
590 
591 
592 /* @func ensFeatureGetAnalysis ************************************************
593 **
594 ** Get the Ensembl Analysis member of an Ensembl Feature.
595 **
596 ** @cc Bio::EnsEMBL::Feature::analysis
597 ** @param [r] feature [const EnsPFeature] Ensembl Feature
598 **
599 ** @return [EnsPAnalysis] Ensembl Analysis or NULL
600 **
601 ** @release 6.2.0
602 ** @@
603 ******************************************************************************/
604 
ensFeatureGetAnalysis(const EnsPFeature feature)605 EnsPAnalysis ensFeatureGetAnalysis(const EnsPFeature feature)
606 {
607     return (feature) ? feature->Analysis : NULL;
608 }
609 
610 
611 
612 
613 /* @func ensFeatureGetEnd *****************************************************
614 **
615 ** Get the end coordinate member of an Ensembl Feature.
616 **
617 ** @cc Bio::EnsEMBL::Feature::end
618 ** @param [r] feature [const EnsPFeature] Ensembl Feature
619 **
620 ** @return [ajint] End coordinate or 0
621 **
622 ** @release 6.2.0
623 ** @@
624 ******************************************************************************/
625 
ensFeatureGetEnd(const EnsPFeature feature)626 ajint ensFeatureGetEnd(const EnsPFeature feature)
627 {
628     return (feature) ? feature->End : 0;
629 }
630 
631 
632 
633 
634 /* @func ensFeatureGetSequencename ********************************************
635 **
636 ** Get the sequence name member of an Ensembl Feature.
637 **
638 ** @cc Bio::EnsEMBL::Feature::seqname
639 ** @param [r] feature [const EnsPFeature] Ensembl Feature
640 **
641 ** @return [AjPStr] Sequence name or NULL
642 **
643 ** @release 6.4.0
644 ** @@
645 ******************************************************************************/
646 
ensFeatureGetSequencename(const EnsPFeature feature)647 AjPStr ensFeatureGetSequencename(const EnsPFeature feature)
648 {
649     return (feature) ? feature->Sequencename : NULL;
650 }
651 
652 
653 
654 
655 /* @func ensFeatureGetSlice ***************************************************
656 **
657 ** Get the Ensembl Slice member of an Ensembl Feature.
658 **
659 ** @cc Bio::EnsEMBL::Feature::slice
660 ** @param [r] feature [const EnsPFeature] Ensembl Feature
661 **
662 ** @return [EnsPSlice] Ensembl Slice or NULL
663 **
664 ** @release 6.2.0
665 ** @@
666 ******************************************************************************/
667 
ensFeatureGetSlice(const EnsPFeature feature)668 EnsPSlice ensFeatureGetSlice(const EnsPFeature feature)
669 {
670     return (feature) ? feature->Slice : NULL;
671 }
672 
673 
674 
675 
676 /* @func ensFeatureGetStart ***************************************************
677 **
678 ** Get the start coordinate member of an Ensembl Feature.
679 **
680 ** @cc Bio::EnsEMBL::Feature::start
681 ** @param [r] feature [const EnsPFeature] Ensembl Feature
682 **
683 ** @return [ajint] Start coordinate or 0
684 **
685 ** @release 6.2.0
686 ** @@
687 ******************************************************************************/
688 
ensFeatureGetStart(const EnsPFeature feature)689 ajint ensFeatureGetStart(const EnsPFeature feature)
690 {
691     return (feature) ? feature->Start : 0;
692 }
693 
694 
695 
696 
697 /* @func ensFeatureGetStrand **************************************************
698 **
699 ** Get the strand orientation member of an Ensembl Feature.
700 **
701 ** @cc Bio::EnsEMBL::Feature::strand
702 ** @param [r] feature [const EnsPFeature] Ensembl Feature
703 **
704 ** @return [ajint] Strand orientation or 0
705 **
706 ** @release 6.2.0
707 ** @@
708 ******************************************************************************/
709 
ensFeatureGetStrand(const EnsPFeature feature)710 ajint ensFeatureGetStrand(const EnsPFeature feature)
711 {
712     return (feature) ? feature->Strand : 0;
713 }
714 
715 
716 
717 
718 /* @section member assignment *************************************************
719 **
720 ** Functions for assigning members of an Ensembl Feature object.
721 **
722 ** @fdata [EnsPFeature]
723 **
724 ** @nam3rule Set Set one member of a Feature
725 ** @nam4rule Analysis Set the Ensembl Analysis
726 ** @nam4rule End Set the end
727 ** @nam4rule Sequencename Set the sequence name
728 ** @nam4rule Slice Set the Ensembl Slice
729 ** @nam4rule Start Set the start
730 ** @nam4rule Strand Set the strand
731 **
732 ** @argrule * feature [EnsPFeature] Ensembl Feature object
733 ** @argrule Analysis analysis [EnsPAnalysis] Ensembl Analysis
734 ** @argrule End end [ajint] End coordinate
735 ** @argrule Sequencename seqname [AjPStr] Sequence name
736 ** @argrule Slice slice [EnsPSlice] Ensembl Slice
737 ** @argrule Start start [ajint] Start coordinate
738 ** @argrule Strand strand [ajint] Strand orientation
739 **
740 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
741 **
742 ** @fcategory modify
743 ******************************************************************************/
744 
745 
746 
747 
748 /* @func ensFeatureSetAnalysis ************************************************
749 **
750 ** Set the Ensembl Analysis member of an Ensembl Feature.
751 **
752 ** @cc Bio::EnsEMBL::Feature::analysis
753 ** @param [u] feature [EnsPFeature] Ensembl Feature
754 ** @param [u] analysis [EnsPAnalysis] Ensembl Analysis
755 **
756 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
757 **
758 ** @release 6.2.0
759 ** @@
760 ******************************************************************************/
761 
ensFeatureSetAnalysis(EnsPFeature feature,EnsPAnalysis analysis)762 AjBool ensFeatureSetAnalysis(EnsPFeature feature, EnsPAnalysis analysis)
763 {
764     if (!feature)
765         return ajFalse;
766 
767     ensAnalysisDel(&feature->Analysis);
768 
769     feature->Analysis = ensAnalysisNewRef(analysis);
770 
771     return ajTrue;
772 }
773 
774 
775 
776 
777 /* @func ensFeatureSetEnd *****************************************************
778 **
779 ** Set the end coordinate member of an Ensembl Feature.
780 **
781 ** @cc Bio::EnsEMBL::Feature::end
782 ** @param [u] feature [EnsPFeature] Ensembl Feature
783 ** @param [r] end [ajint] End coordinate
784 **
785 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
786 **
787 ** @release 6.2.0
788 ** @@
789 ******************************************************************************/
790 
ensFeatureSetEnd(EnsPFeature feature,ajint end)791 AjBool ensFeatureSetEnd(EnsPFeature feature, ajint end)
792 {
793     if (!feature)
794         return ajFalse;
795 
796     feature->End = end;
797 
798     return ajTrue;
799 }
800 
801 
802 
803 
804 /* @func ensFeatureSetSequencename ********************************************
805 **
806 ** Set the sequence name member of an Ensembl Feature.
807 **
808 ** @cc Bio::EnsEMBL::Feature::seqname
809 ** @param [u] feature [EnsPFeature] Ensembl Feature
810 ** @param [u] seqname [AjPStr] Sequence name
811 **
812 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
813 **
814 ** @release 6.4.0
815 ** @@
816 ******************************************************************************/
817 
ensFeatureSetSequencename(EnsPFeature feature,AjPStr seqname)818 AjBool ensFeatureSetSequencename(EnsPFeature feature, AjPStr seqname)
819 {
820     if (!feature)
821         return ajFalse;
822 
823     ajStrDel(&feature->Sequencename);
824 
825     feature->Sequencename = ajStrNewRef(seqname);
826 
827     return ajTrue;
828 }
829 
830 
831 
832 
833 /* @func ensFeatureSetSlice ***************************************************
834 **
835 ** Set the Ensembl Slice member of an Ensembl Feature.
836 **
837 ** @cc Bio::EnsEMBL::Feature::slice
838 ** @param [u] feature [EnsPFeature] Ensembl Feature
839 ** @param [u] slice [EnsPSlice] Ensembl Slice
840 **
841 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
842 **
843 ** @release 6.2.0
844 ** @@
845 ******************************************************************************/
846 
ensFeatureSetSlice(EnsPFeature feature,EnsPSlice slice)847 AjBool ensFeatureSetSlice(EnsPFeature feature, EnsPSlice slice)
848 {
849     if (!feature)
850         return ajFalse;
851 
852     ensSliceDel(&feature->Slice);
853 
854     feature->Slice = ensSliceNewRef(slice);
855 
856     return ajTrue;
857 }
858 
859 
860 
861 
862 /* @func ensFeatureSetStart ***************************************************
863 **
864 ** Set the start coordinate member of an Ensembl Feature.
865 **
866 ** @cc Bio::EnsEMBL::Feature::start
867 ** @param [u] feature [EnsPFeature] Ensembl Feature
868 ** @param [r] start [ajint] Start coordinate
869 **
870 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
871 **
872 ** @release 6.2.0
873 ** @@
874 ******************************************************************************/
875 
ensFeatureSetStart(EnsPFeature feature,ajint start)876 AjBool ensFeatureSetStart(EnsPFeature feature, ajint start)
877 {
878     if (!feature)
879         return ajFalse;
880 
881     feature->Start = start;
882 
883     return ajTrue;
884 }
885 
886 
887 
888 
889 /* @func ensFeatureSetStrand **************************************************
890 **
891 ** Set the strand orientation member of an Ensembl Feature.
892 **
893 ** @cc Bio::EnsEMBL::Feature::strand
894 ** @param [u] feature [EnsPFeature] Ensembl Feature
895 ** @param [r] strand [ajint] Strand orientation
896 **
897 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
898 **
899 ** @release 6.2.0
900 ** @@
901 ******************************************************************************/
902 
ensFeatureSetStrand(EnsPFeature feature,ajint strand)903 AjBool ensFeatureSetStrand(EnsPFeature feature, ajint strand)
904 {
905     if (!feature)
906         return ajFalse;
907 
908     feature->Strand = strand;
909 
910     return ajTrue;
911 }
912 
913 
914 
915 
916 /* @section debugging *********************************************************
917 **
918 ** Functions for reporting of an Ensembl Feature object.
919 **
920 ** @fdata [EnsPFeature]
921 **
922 ** @nam3rule Trace Report Ensembl Feature members to debug file
923 **
924 ** @argrule Trace feature [const EnsPFeature] Ensembl Feature
925 ** @argrule Trace level [ajuint] Indentation level
926 **
927 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
928 **
929 ** @fcategory misc
930 ******************************************************************************/
931 
932 
933 
934 
935 /* @func ensFeatureTrace ******************************************************
936 **
937 ** Trace an Ensembl Feature.
938 **
939 ** @param [r] feature [const EnsPFeature] Ensembl Feature
940 ** @param [r] level [ajuint] Indentation level
941 **
942 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
943 **
944 ** @release 6.2.0
945 ** @@
946 ******************************************************************************/
947 
ensFeatureTrace(const EnsPFeature feature,ajuint level)948 AjBool ensFeatureTrace(const EnsPFeature feature, ajuint level)
949 {
950     AjPStr indent = NULL;
951 
952     if (!feature)
953         return ajFalse;
954 
955     indent = ajStrNew();
956 
957     ajStrAppendCountK(&indent, ' ', level * 2);
958 
959     ajDebug("%SensFeatureTrace %p\n"
960             "%S  Slice %p\n"
961             "%S  Start %d\n"
962             "%S  End %d\n"
963             "%S  Strand %d\n"
964             "%S  Analysis %p\n"
965             "%S  Sequencename '%S'\n"
966             "%S  Use %u\n",
967             indent, feature,
968             indent, feature->Slice,
969             indent, feature->Start,
970             indent, feature->End,
971             indent, feature->Strand,
972             indent, feature->Analysis,
973             indent, feature->Sequencename,
974             indent, feature->Use);
975 
976     ensSliceTrace(feature->Slice, level + 1);
977 
978     ensAnalysisTrace(feature->Analysis, level + 1);
979 
980     ajStrDel(&indent);
981 
982     return ajTrue;
983 }
984 
985 
986 
987 
988 /* @section calculate *********************************************************
989 **
990 ** Functions for calculating information from an Ensembl Feature object.
991 **
992 ** @fdata [EnsPFeature]
993 **
994 ** @nam3rule Calculate Calculate Ensembl Feature information
995 ** @nam4rule Length  Calculate the length
996 ** @nam4rule Memsize Calculate the memory size in bytes
997 ** @nam4rule Strand  Calculate the strand
998 **
999 ** @argrule * feature [const EnsPFeature] Ensembl Feature
1000 **
1001 ** @valrule Length [ajuint] Length or 0U
1002 ** @valrule Memsize [size_t] Memory size in bytes or 0
1003 ** @valrule Strand [char] Strand '+', '\0' or '-'
1004 **
1005 ** @fcategory misc
1006 ******************************************************************************/
1007 
1008 
1009 
1010 
1011 /* @func ensFeatureCalculateLength ********************************************
1012 **
1013 ** Calculate the length of an Ensembl Feature.
1014 **
1015 ** @cc Bio::EnsEMBL::Feature::length
1016 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1017 **
1018 ** @return [ajuint] Length or 0U
1019 **
1020 ** @release 6.4.0
1021 ** @@
1022 ******************************************************************************/
1023 
ensFeatureCalculateLength(const EnsPFeature feature)1024 ajuint ensFeatureCalculateLength(const EnsPFeature feature)
1025 {
1026     if (!feature)
1027         return 0U;
1028 
1029     if (feature->Slice != NULL)
1030         return ensSliceCalculateRegion(feature->Slice,
1031                                        feature->Start,
1032                                        feature->End);
1033 
1034     if (feature->Start > feature->End)
1035         ajFatal("ensFeatureCalculateLength cannot calculate the length of an "
1036                 "Ensembl Feature presumably on a circular Ensembl Slice, "
1037                 "without an Ensembl Slice.");
1038 
1039     return feature->End - feature->Start + 1U;
1040 }
1041 
1042 
1043 
1044 
1045 /* @func ensFeatureCalculateMemsize *******************************************
1046 **
1047 ** Calculate the memory size in bytes of an Ensembl Feature.
1048 **
1049 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1050 **
1051 ** @return [size_t] Memory size in bytes or 0
1052 **
1053 ** @release 6.4.0
1054 ** @@
1055 ******************************************************************************/
1056 
ensFeatureCalculateMemsize(const EnsPFeature feature)1057 size_t ensFeatureCalculateMemsize(const EnsPFeature feature)
1058 {
1059     size_t size = 0;
1060 
1061     if (!feature)
1062         return 0;
1063 
1064     size += sizeof (EnsOFeature);
1065 
1066     size += ensSliceCalculateMemsize(feature->Slice);
1067 
1068     size += ensAnalysisCalculateMemsize(feature->Analysis);
1069 
1070     if (feature->Sequencename)
1071     {
1072         size += sizeof (AjOStr);
1073 
1074         size += ajStrGetRes(feature->Sequencename);
1075     }
1076 
1077     return size;
1078 }
1079 
1080 
1081 
1082 
1083 /* @func ensFeatureCalculateStrand ********************************************
1084 **
1085 ** Calculate the strand of an Ensembl Feature.
1086 **
1087 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1088 **
1089 ** @return [char] Strand '+', '\0' or '-'
1090 **
1091 ** @release 6.5.0
1092 ** @@
1093 ******************************************************************************/
1094 
ensFeatureCalculateStrand(const EnsPFeature feature)1095 char ensFeatureCalculateStrand(const EnsPFeature feature)
1096 {
1097     if (!feature)
1098         return '\0';
1099 
1100     if (feature->Strand > 0)
1101         return '+';
1102 
1103     if (feature->Strand < 0)
1104         return '-';
1105 
1106     return '\0';
1107 }
1108 
1109 
1110 
1111 
1112 /* @section convenience functions *********************************************
1113 **
1114 ** Ensembl Feature convenience functions
1115 **
1116 ** @fdata [EnsPFeature]
1117 **
1118 ** @nam3rule Get Get member(s) of associated objects
1119 ** @nam4rule Seqregion Get an Ensembl Sequence Region of an Ensembl Slice
1120 ** @nam5rule End Get an Ensembl Sequence Region end
1121 ** @nam5rule Length Get an Ensembl Sequence Region length
1122 ** @nam5rule Name Get an Ensembl Sequence region name
1123 ** @nam5rule Object Get an Ensembl Sequence Region object
1124 ** @nam5rule Start Get an Ensembl Sequence Region start
1125 ** @nam5rule Strand Get an Ensembl Sequence Region strand
1126 **
1127 ** @argrule * feature [const EnsPFeature] Ensembl Feature
1128 **
1129 ** @valrule SeqregionEnd [ajint] Ensembl Sequence Region end or 0
1130 ** @valrule SeqregionLength [ajuint] Ensembl Sequence Region length or 0U
1131 ** @valrule SeqregionName [const AjPStr] Ensembl Sequence Region name or NULL
1132 ** @valrule SeqregionObject [const EnsPSeqregion] Ensembl Sequence Region or
1133 ** NULL
1134 ** @valrule SeqregionStart [ajint] Ensembl Sequence Region start or 0
1135 ** @valrule SeqregionStrand [ajint] Ensembl Sequence Region strand or 0
1136 **
1137 ** @fcategory use
1138 ******************************************************************************/
1139 
1140 
1141 
1142 
1143 /* @func ensFeatureGetSeqregionEnd ********************************************
1144 **
1145 ** Get the end coordinate of an Ensembl Feature relative to the
1146 ** Ensembl Sequence Region member of the Ensembl Slice member of an
1147 ** Ensembl Feature.
1148 **
1149 ** @cc Bio::EnsEMBL::Feature::seq_region_end
1150 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1151 **
1152 ** @return [ajint] End coordinate on an Ensembl Sequence Region or 0
1153 **
1154 ** @release 6.2.0
1155 ** @@
1156 ******************************************************************************/
1157 
ensFeatureGetSeqregionEnd(const EnsPFeature feature)1158 ajint ensFeatureGetSeqregionEnd(const EnsPFeature feature)
1159 {
1160     ajint srend    = 0;
1161     ajint srlength = 0;
1162 
1163     AjBool circular = AJFALSE;
1164 
1165     if (!feature)
1166         return 0;
1167 
1168     if (!feature->Slice)
1169         return 0;
1170 
1171     if (ensSliceIsCircular(feature->Slice, &circular) == ajFalse)
1172         return 0;
1173 
1174     srlength = ensSliceGetSeqregionLength(feature->Slice);
1175 
1176     if (ensSliceGetStrand(feature->Slice) >= 0)
1177         srend = ensSliceGetStart(feature->Slice) + feature->End   - 1;
1178     else
1179         srend = ensSliceGetEnd(feature->Slice)   - feature->Start + 1;
1180 
1181     if ((srend > srlength) && (circular == ajTrue))
1182         srend -= srlength;
1183 
1184     return srend;
1185 }
1186 
1187 
1188 
1189 
1190 /* @func ensFeatureGetSeqregionLength *****************************************
1191 **
1192 ** Get the length member of the Ensembl Sequence Region member of the
1193 ** Ensembl Slice member of an Ensembl Feature.
1194 **
1195 ** @cc Bio::EnsEMBL::Feature::seq_region_length
1196 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1197 **
1198 ** @return [ajuint] Ensembl Sequence Region length or 0U
1199 **
1200 ** @release 6.2.0
1201 ** @@
1202 ******************************************************************************/
1203 
ensFeatureGetSeqregionLength(const EnsPFeature feature)1204 ajuint ensFeatureGetSeqregionLength(const EnsPFeature feature)
1205 {
1206     return (feature &&
1207             feature->Slice) ?
1208         (ajuint) ensSliceGetSeqregionLength(feature->Slice) : 0U;
1209 }
1210 
1211 
1212 
1213 
1214 /* @func ensFeatureGetSeqregionName *******************************************
1215 **
1216 ** Get the name member of the Ensembl Sequence Region member of the
1217 ** Ensembl Slice member of an Ensembl Feature.
1218 **
1219 ** @cc Bio::EnsEMBL::Feature::seq_region_name
1220 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1221 **
1222 ** @return [const AjPStr] Ensembl Sequence Region name or NULL
1223 **
1224 ** @release 6.2.0
1225 ** @@
1226 ******************************************************************************/
1227 
ensFeatureGetSeqregionName(const EnsPFeature feature)1228 const AjPStr ensFeatureGetSeqregionName(const EnsPFeature feature)
1229 {
1230     return (feature &&
1231             feature->Slice) ?
1232         ensSliceGetSeqregionName(feature->Slice) : NULL;
1233 }
1234 
1235 
1236 
1237 
1238 /* @func ensFeatureGetSeqregionObject *****************************************
1239 **
1240 ** Get the Ensembl Sequence Region member of the
1241 ** Ensembl Slice member of an Ensembl Feature.
1242 **
1243 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1244 **
1245 ** @return [const EnsPSeqregion] Ensembl Sequence Region or NULL
1246 **
1247 ** @release 6.4.0
1248 ** @@
1249 ******************************************************************************/
1250 
ensFeatureGetSeqregionObject(const EnsPFeature feature)1251 const EnsPSeqregion ensFeatureGetSeqregionObject(const EnsPFeature feature)
1252 {
1253     return (feature &&
1254             feature->Slice) ?
1255         ensSliceGetSeqregion(feature->Slice) : NULL;
1256 }
1257 
1258 
1259 
1260 
1261 /* @func ensFeatureGetSeqregionStart ******************************************
1262 **
1263 ** Get the start coordinate of an Ensembl Feature relative to the
1264 ** Ensembl Sequence Region member of the Ensembl Slice member of an
1265 ** Ensembl Feature.
1266 **
1267 ** @cc Bio::EnsEMBL::Feature::seq_region_start
1268 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1269 **
1270 ** @return [ajint] Start coordinate on an Ensembl Sequence Region or 0
1271 **
1272 ** @release 6.2.0
1273 ** @@
1274 ******************************************************************************/
1275 
ensFeatureGetSeqregionStart(const EnsPFeature feature)1276 ajint ensFeatureGetSeqregionStart(const EnsPFeature feature)
1277 {
1278     ajint srstart  = 0;
1279     ajint srlength = 0;
1280 
1281     AjBool circular = AJFALSE;
1282 
1283     if (!feature)
1284         return 0;
1285 
1286     if (!feature->Slice)
1287         return 0;
1288 
1289     if (ensSliceIsCircular(feature->Slice, &circular) == ajFalse)
1290         return 0;
1291 
1292     srlength = ensSliceGetSeqregionLength(feature->Slice);
1293 
1294     if (ensSliceGetStrand(feature->Slice) >= 0)
1295     {
1296         if ((feature->Start < 0) && (circular == ajTrue))
1297             srstart = srlength + feature->Start;
1298         else
1299             srstart = ensSliceGetStart(feature->Slice) + feature->Start - 1;
1300     }
1301     else
1302         srstart = ensSliceGetEnd(feature->Slice) - feature->End + 1;
1303 
1304     if ((srstart > srlength) && (circular == ajTrue))
1305         srstart -= srlength;
1306 
1307     return srstart;
1308 }
1309 
1310 
1311 
1312 
1313 /* @func ensFeatureGetSeqregionStrand *****************************************
1314 **
1315 ** Get the strand information of an Ensembl Feature relative to the
1316 ** Ensembl Sequence Region member of the Ensembl Slice member of an
1317 ** Ensembl Feature.
1318 **
1319 ** @cc Bio::EnsEMBL::Feature::seq_region_strand
1320 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1321 **
1322 ** @return [ajint] Strand information on an Ensembl Sequence Region or 0
1323 **
1324 ** @release 6.2.0
1325 ** @@
1326 ******************************************************************************/
1327 
ensFeatureGetSeqregionStrand(const EnsPFeature feature)1328 ajint ensFeatureGetSeqregionStrand(const EnsPFeature feature)
1329 {
1330     return (feature &&
1331             feature->Slice) ?
1332         (ensSliceGetStrand(feature->Slice) * feature->Strand) : 0;
1333 }
1334 
1335 
1336 
1337 
1338 /* @section fetch *************************************************************
1339 **
1340 ** Functions for fetching objects of an
1341 ** Ensembl Feature object.
1342 **
1343 ** @fdata [EnsPFeature]
1344 **
1345 ** @nam3rule Fetch Fetch object from an Ensembl Feature
1346 ** @nam4rule All
1347 ** @nam5rule Alternativelocations Fetch all alternative locations
1348 ** @nam4rule Sequencename Fetch the sequence name
1349 **
1350 ** @argrule Alternativelocations feature [EnsPFeature] Ensembl Feature
1351 ** @argrule Alternativelocations all [AjBool] Fetch all Ensembl Feature objects
1352 ** @argrule Alternativelocations features [AjPList] AJAX List of
1353 **                                                  Ensembl Feature objects
1354 ** @argrule Sequencename feature [const EnsPFeature] Ensembl Feature
1355 ** @argrule Sequencename Pname [AjPStr*] Sequence name
1356 **
1357 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
1358 **
1359 ** @fcategory misc
1360 ******************************************************************************/
1361 
1362 
1363 
1364 
1365 /* @func ensFeatureFetchAllAlternativelocations *******************************
1366 **
1367 ** Fetch all alternative locations of an Ensembl Feature on other symlinked
1368 ** Ensembl Slice.
1369 **
1370 ** The caller is responsible for deleting the Ensembl Feature objects before
1371 ** deleting the AJAX List.
1372 **
1373 ** @cc Bio::EnsEMBL::Feature::get_all_alt_locations
1374 ** @param [u] feature [EnsPFeature] Ensembl Feature
1375 ** @param [r] all [AjBool] Fetch all Ensembl Feature objects
1376 ** @param [u] features [AjPList] AJAX List of Ensembl Feature objects
1377 **
1378 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1379 **
1380 ** @release 6.4.0
1381 ** @@
1382 ******************************************************************************/
1383 
ensFeatureFetchAllAlternativelocations(EnsPFeature feature,AjBool all,AjPList features)1384 AjBool ensFeatureFetchAllAlternativelocations(EnsPFeature feature,
1385                                               AjBool all,
1386                                               AjPList features)
1387 {
1388     ajint alength = 0;
1389     ajint rlength = 0;
1390 
1391     ajuint srid = 0U;
1392 
1393     AjPList aefs = NULL;
1394     AjPList haps = NULL;
1395     AjPList alts = NULL;
1396 
1397     EnsPAssemblyexceptionfeature        aef  = NULL;
1398     EnsPAssemblyexceptionfeature       naef  = NULL;
1399     EnsPAssemblyexceptionfeatureadaptor aefa = NULL;
1400 
1401     EnsPDatabaseadaptor dba = NULL;
1402 
1403     EnsPFeature afeature = NULL;
1404     EnsPFeature nfeature = NULL;
1405 
1406     EnsPSlice fslice     = NULL;
1407     EnsPSlice rslice     = NULL;
1408     EnsPSlice aslice     = NULL;
1409     EnsPSlice nslice     = NULL;
1410     EnsPSliceadaptor sla = NULL;
1411 
1412     if (!feature)
1413         return ajFalse;
1414 
1415     fslice = feature->Slice;
1416 
1417     if (!fslice)
1418         return ajTrue;
1419 
1420     sla = ensSliceGetAdaptor(fslice);
1421 
1422     if (!sla)
1423         return ajTrue;
1424 
1425     /*
1426     ** Fetch all Ensembl Assembly Exception Feature objects for the
1427     ** full-length Slice of the Ensembl Sequence Region member.
1428     */
1429 
1430     dba = ensSliceadaptorGetDatabaseadaptor(sla);
1431 
1432     srid = ensSliceGetSeqregionIdentifier(fslice);
1433 
1434     ensSliceadaptorFetchBySeqregionIdentifier(sla, srid, 0, 0, 0, &rslice);
1435 
1436     aefa = ensRegistryGetAssemblyexceptionfeatureadaptor(dba);
1437 
1438     aefs = ajListNew();
1439 
1440     ensAssemblyexceptionfeatureadaptorFetchAllbySlice(
1441         aefa,
1442         rslice,
1443         aefs);
1444 
1445     /*
1446     ** Group Ensembl Assembly Exception Feature objects based on their
1447     ** Ensembl Assembly Exception Type enumeration member into
1448     ** haplotypes (HAPs) and pseudo-autosomal regions (PARs) initially.
1449     */
1450 
1451     haps = ajListNew();
1452     alts = ajListNew();
1453 
1454     while (ajListPop(aefs, (void **) &aef))
1455     {
1456         switch (ensAssemblyexceptionfeatureGetType(aef))
1457         {
1458             case ensEAssemblyexceptionTypeHAP:           /* fall through */
1459             case ensEAssemblyexceptionTypePatchFix:      /* fall through */
1460             case ensEAssemblyexceptionTypePatchNovel:    /* fall through */
1461 
1462                 ajListPushAppend(haps, (void *) aef);
1463 
1464                 break;
1465 
1466             case ensEAssemblyexceptionTypePAR:
1467 
1468                 ajListPushAppend(alts, (void *) aef);
1469 
1470                 break;
1471 
1472             case ensEAssemblyexceptionTypeHAPRef:        /* fall through */
1473             case ensEAssemblyexceptionTypePatchNovelRef: /* fall through */
1474             case ensEAssemblyexceptionTypePatchFixRef:   /* fall through */
1475 
1476                 if (all)
1477                     ajListPushAppend(haps, (void *) aef);
1478 
1479                 break;
1480 
1481             default:
1482 
1483                 ajDebug("ensFeatureFetchAllAlternativelocations got unknown "
1484                         "EnsEAssemblyexceptionType (%d).\n",
1485                         ensAssemblyexceptionfeatureGetType(aef));
1486         }
1487     }
1488 
1489     ajListFree(&aefs);
1490 
1491     /*
1492     ** Regions surrounding haplotypes are those of interest, not the haplotype
1493     ** itself. Convert haplotype Ensembl Assembly Exception Feature objects to
1494     ** regions around haplotypes instead.
1495     */
1496 
1497     while (ajListPop(haps, (void **) &aef))
1498     {
1499         afeature = ensAssemblyexceptionfeatureGetFeature(aef);
1500 
1501         aslice = ensAssemblyexceptionfeatureGetExceptionSlice(aef);
1502 
1503         if ((ensFeatureGetStart(afeature) > 1) &&
1504             (ensSliceGetStart(aslice) > 1))
1505         {
1506             /* Copy the Feature and re-set the start and end cordinates. */
1507 
1508             nfeature = ensFeatureNewCpy(afeature);
1509 
1510             ensFeatureSetStart(nfeature, 1);
1511 
1512             ensFeatureSetEnd(nfeature, ensFeatureGetStart(afeature) - 1);
1513 
1514             ensSliceadaptorFetchBySeqregionIdentifier(
1515                 sla,
1516                 ensSliceGetSeqregionIdentifier(aslice),
1517                 1,
1518                 ensSliceGetStart(aslice) - 1,
1519                 ensSliceGetStrand(aslice),
1520                 &nslice);
1521 
1522             naef = ensAssemblyexceptionfeatureNewIni(
1523                 aefa,
1524                 0,
1525                 nfeature,
1526                 nslice,
1527                 ensAssemblyexceptionfeatureGetType(aef));
1528 
1529             ajListPushAppend(alts, (void *) naef);
1530 
1531             ensSliceDel(&nslice);
1532 
1533             ensFeatureDel(&nfeature);
1534         }
1535 
1536         /* Check that Ensembl Slice lengths are within range. */
1537 
1538         if (ensSliceGetSeqregionLength(rslice) <= INT_MAX)
1539             rlength = ensSliceGetSeqregionLength(rslice);
1540         else
1541             ajFatal("ensFeatureFetchAllAlternativelocations got "
1542                     "Sequence Region length (%d) exceeding MAX_INT (%d).\n",
1543                     ensSliceGetSeqregionLength(rslice),
1544                     INT_MAX);
1545 
1546         if (ensSliceGetSeqregionLength(aslice) <= INT_MAX)
1547             alength = ensSliceGetSeqregionLength(aslice);
1548         else
1549             ajFatal("ensFeatureFetchAllAlternativelocations got "
1550                     "Sequence Region length (%d) exceeding MAX_INT (%d).\n",
1551                     ensSliceGetSeqregionLength(aslice),
1552                     INT_MAX);
1553 
1554         if ((ensFeatureGetEnd(afeature) < rlength) &&
1555             (ensSliceGetEnd(aslice) < alength))
1556         {
1557             /* Copy the Feature and re-set the start and end cordinates. */
1558 
1559             nfeature = ensFeatureNewCpy(afeature);
1560 
1561             ensFeatureSetStart(nfeature, ensFeatureGetEnd(afeature) + 1);
1562 
1563             ensFeatureSetEnd(nfeature, ensFeatureGetSeqregionLength(afeature));
1564 
1565             ensSliceadaptorFetchBySeqregionIdentifier(
1566                 sla,
1567                 ensSliceGetSeqregionIdentifier(aslice),
1568                 ensSliceGetEnd(aslice) + 1,
1569                 ensSliceGetSeqregionLength(aslice),
1570                 ensSliceGetStrand(aslice),
1571                 &nslice);
1572 
1573             naef = ensAssemblyexceptionfeatureNewIni(
1574                 aefa,
1575                 0,
1576                 nfeature,
1577                 nslice,
1578                 ensAssemblyexceptionfeatureGetType(aef));
1579 
1580             ajListPushAppend(alts, (void *) naef);
1581 
1582             ensSliceDel(&nslice);
1583         }
1584 
1585         ensAssemblyexceptionfeatureDel(&aef);
1586     }
1587 
1588     ajListFree(&haps);
1589 
1590     /* Check if exception regions contain our Feature. */
1591 
1592     while (ajListPop(alts, (void **) &aef))
1593     {
1594         afeature = ensAssemblyexceptionfeatureGetFeature(aef);
1595 
1596         aslice = ensAssemblyexceptionfeatureGetExceptionSlice(aef);
1597 
1598         /* Ignore the other region if the Feature is not entirely on it. */
1599 
1600         if ((ensFeatureGetSeqregionStart(feature)
1601              < ensFeatureGetStart(afeature)) ||
1602             (ensFeatureGetSeqregionEnd(feature)
1603              > ensFeatureGetEnd(afeature)))
1604         {
1605             ensAssemblyexceptionfeatureDel(&aef);
1606 
1607             continue;
1608         }
1609 
1610         nfeature = ensFeatureNewCpy(feature);
1611 
1612         /* Position the Feature on the entire Slice of the other region. */
1613 
1614         nfeature->Start = ensFeatureGetSeqregionStart(nfeature)
1615             - ensFeatureGetStart(afeature)
1616             + ensSliceGetStart(aslice);
1617 
1618         nfeature->End = ensFeatureGetSeqregionEnd(nfeature)
1619             - ensFeatureGetStart(afeature)
1620             + ensSliceGetStart(aslice);
1621 
1622         nfeature->Strand *= ensSliceGetStrand(aslice);
1623 
1624         /*
1625         ** Place the new Feature objects on the full-length Slice of the
1626         ** Ensembl Sequence Region member.
1627         */
1628 
1629         ensSliceadaptorFetchBySeqregionIdentifier(
1630             sla,
1631             ensSliceGetSeqregionIdentifier(aslice),
1632             0,
1633             0,
1634             0,
1635             &nslice);
1636 
1637         ensFeatureSetSlice(nfeature, nslice);
1638 
1639         ajListPushAppend(features, (void *) nfeature);
1640 
1641         ensSliceDel(&nslice);
1642     }
1643 
1644     ajListFree(&alts);
1645 
1646     ensSliceDel(&fslice);
1647 
1648     return ajTrue;
1649 }
1650 
1651 
1652 
1653 
1654 /* @func ensFeatureFetchSequencename ******************************************
1655 **
1656 ** Fetch the name of the sequence, on which an Ensembl Feature is annotated.
1657 ** The name is the Ensembl Feature sequence name member or, if not available,
1658 ** the name of the underlying Ensembl Slice.
1659 **
1660 ** @cc Bio::EnsEMBL::Feature::seqname
1661 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1662 ** @param [wP] Pname [AjPStr*] Sequence name
1663 **
1664 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1665 **
1666 ** @release 6.4.0
1667 ** @@
1668 ******************************************************************************/
1669 
ensFeatureFetchSequencename(const EnsPFeature feature,AjPStr * Pname)1670 AjBool ensFeatureFetchSequencename(const EnsPFeature feature, AjPStr *Pname)
1671 {
1672     if (!feature)
1673         return ajFalse;
1674 
1675     if (!Pname)
1676         return ajFalse;
1677 
1678     if (*Pname)
1679         ajStrAssignClear(Pname);
1680     else
1681         *Pname = ajStrNew();
1682 
1683     if (feature->Sequencename && ajStrGetLen(feature->Sequencename))
1684         ajStrAssignS(Pname, feature->Sequencename);
1685     else if (feature->Slice)
1686         ensSliceFetchName(feature->Slice, Pname);
1687 
1688     return ajTrue;
1689 }
1690 
1691 
1692 
1693 
1694 /* @section map ***************************************************************
1695 **
1696 ** Functions for mapping Ensembl Feature objects between
1697 ** Ensembl Coordinate System objects.
1698 **
1699 ** @fdata [EnsPFeature]
1700 **
1701 ** @nam3rule Move Move an Ensembl Feature
1702 ** @nam3rule Project Project an Ensembl Feature
1703 ** @nam3rule Projectslice Project an Ensembl Feature onto an Ensembl Slice
1704 ** @nam3rule Transfer Transfer an Ensembl Feature
1705 ** @nam3rule Transform Transform an Ensembl Feature
1706 **
1707 ** @argrule Move feature [EnsPFeature] Ensembl Feature
1708 ** @argrule Move start [ajint] Start coordinate
1709 ** @argrule Move end [ajint] End coordinate
1710 ** @argrule Move strand [ajint] Strand orientation
1711 ** @argrule Project feature [const EnsPFeature] Ensembl Feature
1712 ** @argrule Project csname [const AjPStr] Ensembl Coordinate System name
1713 ** @argrule Project csversion [const AjPStr] Ensembl Coordinate System version
1714 ** @argrule Project pss [AjPList] AJAX List of
1715 ** Ensembl Projection Segment objects
1716 ** @argrule Projectslice feature [const EnsPFeature] Ensembl Feature
1717 ** @argrule Projectslice slice [EnsPSlice] Ensembl Slice
1718 ** @argrule Projectslice pss [AjPList] AJAX List of
1719 ** Ensembl Projection Segment objects
1720 ** @argrule Transfer feature [EnsPFeature] Ensembl Feature
1721 ** @argrule Transfer slice [EnsPSlice] Ensembl Slice
1722 ** @argrule Transform feature [EnsPFeature] Ensembl Feature
1723 ** @argrule Transform csname [const AjPStr]
1724 ** Ensembl Coordinate System name
1725 ** @argrule Transform csversion [const AjPStr]
1726 ** Ensembl Coordinate System version
1727 ** @argrule Transform slice [EnsPSlice] Ensembl Slice
1728 **
1729 ** @valrule Move [AjBool] ajTrue upon success, ajFalse otherwise
1730 ** @valrule Project [AjBool] ajTrue upon success, ajFalse otherwise
1731 ** @valrule Projectslice [AjBool] ajTrue upon success, ajFalse otherwise
1732 ** @valrule Transfer [EnsPFeature] Ensembl Feature or NULL
1733 ** @valrule Transform [EnsPFeature] Ensembl Feature or NULL
1734 **
1735 ** @fcategory misc
1736 ******************************************************************************/
1737 
1738 
1739 
1740 
1741 /* @func ensFeatureMove *******************************************************
1742 **
1743 ** Move an Ensembl Feature on its Slice. This function sets the start and end
1744 ** coordinate, as well as the strand orientation simultaneously.
1745 **
1746 ** @cc Bio::EnsEMBL::Feature::move
1747 ** @param [u] feature [EnsPFeature] Ensembl Feature
1748 ** @param [r] start [ajint] Start coordinate
1749 ** @param [r] end [ajint] End coordinate
1750 ** @param [r] strand [ajint] Strand orientation
1751 **
1752 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1753 **
1754 ** @release 6.2.0
1755 ** @@
1756 ******************************************************************************/
1757 
ensFeatureMove(EnsPFeature feature,ajint start,ajint end,ajint strand)1758 AjBool ensFeatureMove(EnsPFeature feature,
1759                       ajint start,
1760                       ajint end,
1761                       ajint strand)
1762 {
1763     if (!feature)
1764         return ajFalse;
1765 
1766     if (start && end && (end < start))
1767     {
1768         ajDebug("ensFeatureMove start (%d) must be less than or equal to the "
1769                 "end coordinate (%d).\n", start, end);
1770 
1771         return ajFalse;
1772     }
1773 
1774     if ((strand < -1) || (strand > 1))
1775     {
1776         ajDebug("ensFeatureMove strand (%d) must be +1, 0 or -1.\n", strand);
1777 
1778         return ajFalse;
1779     }
1780 
1781     feature->Start  = start;
1782     feature->End    = end;
1783     feature->Strand = strand;
1784 
1785     return ajTrue;
1786 }
1787 
1788 
1789 
1790 
1791 /* @func ensFeatureProject ****************************************************
1792 **
1793 ** Project an Ensembl Feature into another Ensembl Coordinate System.
1794 **
1795 ** @cc Bio::EnsEMBL::Feature::project
1796 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1797 ** @param [r] csname [const AjPStr] Ensembl Coordinate System name
1798 ** @param [rN] csversion [const AjPStr] Ensembl Coordinate System version
1799 ** @param [u] pss [AjPList] AJAX List of Ensembl Projection Segment objects
1800 **
1801 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1802 **
1803 ** @release 6.2.0
1804 ** @@
1805 ** This projection function does not move a Feature to another Slice, but it
1806 ** provides a definition of where a Feature lies in another Coordinate System.
1807 ** This is especially useful to see where a Feature would lie in a
1808 ** Coordinate System in which it crosses (Sequence Region) boundaries.
1809 **
1810 ** Ensembl Projection Segment objects contain source coordinates releative to
1811 ** the Feature start and a target Slice spanning the region in the requested
1812 ** Coordinate System this Feature projects to.
1813 **
1814 ** If the Feature projects entirely into a gap an empty AJAX List will be
1815 ** returned.
1816 ******************************************************************************/
1817 
ensFeatureProject(const EnsPFeature feature,const AjPStr csname,const AjPStr csversion,AjPList pss)1818 AjBool ensFeatureProject(const EnsPFeature feature,
1819                          const AjPStr csname,
1820                          const AjPStr csversion,
1821                          AjPList pss)
1822 {
1823     ajint strand = 0;
1824 
1825     EnsPSlice fslice     = NULL;
1826     EnsPSlice nslice     = NULL;
1827     EnsPSliceadaptor sla = NULL;
1828 
1829     if (!feature)
1830     {
1831         ajDebug("ensFeatureProject requires an Ensembl Feature.\n");
1832 
1833         return ajFalse;
1834     }
1835 
1836     if (!csname)
1837     {
1838         ajDebug("ensFeatureProject requires an "
1839                 "Ensembl Coordinate System name.\n");
1840 
1841         return ajFalse;
1842     }
1843 
1844     /* A Coordinate System version is not strictly required. */
1845 
1846     if (!pss)
1847     {
1848         ajDebug("ensFeatureProject requires an AJAX List.\n");
1849 
1850         return ajFalse;
1851     }
1852 
1853     if (!feature->Slice)
1854     {
1855         ajWarn("ensFeatureProject requires an Ensembl Feature with "
1856                "an Ensembl Slice attached to it.\n");
1857 
1858         return ajFalse;
1859     }
1860 
1861     /*
1862     ** Use the Ensembl Database Adaptor of the Slice as this Feature may not
1863     ** yet be stored in the database and may not have its own Adaptor.
1864     */
1865 
1866     sla = ensSliceGetAdaptor(feature->Slice);
1867 
1868     if (!sla)
1869     {
1870         ajWarn("ensFeatureProject requires an Ensembl Feature with "
1871                "an Ensembl Slice Adaptor member attached to the "
1872                "Ensembl Slice member.\n");
1873 
1874         return ajFalse;
1875     }
1876 
1877     strand = feature->Strand * ensSliceGetStrand(feature->Slice);
1878 
1879     /*
1880     ** The ensSliceadaptorFetchByFeature function always returns a
1881     ** forward-strand Slice.
1882     */
1883 
1884     /*
1885     ** FIXME: So far this is the only instance of ensSliceFetchSliceinverted.
1886     ** Wouldn't ensSliceadaptorFetchByFeature be better if it allowed the
1887     ** specification of a strand?
1888     */
1889 
1890     ensSliceadaptorFetchByFeature(sla, feature, 0, &fslice);
1891 
1892     if (strand < 0)
1893         ensSliceFetchSliceinverted(fslice, &nslice);
1894     else
1895         nslice = ensSliceNewRef(fslice);
1896 
1897     ensSliceDel(&fslice);
1898 
1899     ensSliceProject(nslice, csname, csversion, pss);
1900 
1901     ensSliceDel(&nslice);
1902 
1903     return ajTrue;
1904 }
1905 
1906 
1907 
1908 
1909 /* @func ensFeatureProjectslice ***********************************************
1910 **
1911 ** Project an Ensembl Feature onto an Ensembl Slice.
1912 **
1913 ** @cc Bio::EnsEMBL::Feature::project_to_slice
1914 ** @param [r] feature [const EnsPFeature] Ensembl Feature
1915 ** @param [u] slice [EnsPSlice] Ensembl Slice
1916 ** @param [u] pss [AjPList] AJAX List of Ensembl Projection Segment objects
1917 **
1918 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1919 **
1920 ** @release 6.4.0
1921 ** @@
1922 ** This projection function does not move a Feature to another Slice, but it
1923 ** provides a definition of where a Feature lies in another Coordinate System.
1924 ** This is especially useful to see where a Feature would lie on a
1925 ** Slice on which it crosses (Sequence Region) boundaries.
1926 **
1927 ** Ensembl Projection Segment objects contain source coordinates releative to
1928 ** the Feature start and a target Slice spanning the region in the requested
1929 ** Coordinate System this Feature projects to.
1930 **
1931 ** If the Feature projects entirely into a gap an empty AJAX List will be
1932 ** returned.
1933 ******************************************************************************/
1934 
ensFeatureProjectslice(const EnsPFeature feature,EnsPSlice slice,AjPList pss)1935 AjBool ensFeatureProjectslice(const EnsPFeature feature,
1936                               EnsPSlice slice,
1937                               AjPList pss)
1938 {
1939     ajint strand = 0;
1940 
1941     EnsPSlice fslice     = NULL;
1942     EnsPSlice nslice     = NULL;
1943     EnsPSliceadaptor sla = NULL;
1944 
1945     if (!feature)
1946         return ajFalse;
1947 
1948     if (!slice)
1949         return ajFalse;
1950 
1951     if (!pss)
1952         return ajFalse;
1953 
1954     if (!feature->Slice)
1955     {
1956         ajWarn("ensFeatureProjectslice requires an Ensembl Feature with "
1957                "an Ensembl Slice attached to it.\n");
1958 
1959         return ajFalse;
1960     }
1961 
1962     /*
1963     ** Use the Ensembl Database Adaptor of the Slice as this Feature may not
1964     ** yet be stored in the database and may not have its own Adaptor.
1965     */
1966 
1967     sla = ensSliceGetAdaptor(feature->Slice);
1968 
1969     if (!sla)
1970     {
1971         ajWarn("ensFeatureProjectslice requires an Ensembl Feature with "
1972                "an Ensembl Slice Adaptor member attached to the "
1973                "Ensembl Slice member.\n");
1974 
1975         return ajFalse;
1976     }
1977 
1978     strand = feature->Strand * ensSliceGetStrand(feature->Slice);
1979 
1980     /*
1981     ** The ensSliceadaptorFetchByFeature function always returns a
1982     ** forward-strand Slice.
1983     */
1984 
1985     /*
1986     ** FIXME: So far this is the only instance of ensSliceFetchSliceinverted.
1987     ** Wouldn't ensSliceadaptorFetchByFeature be better if it allowed the
1988     ** specification of a strand?
1989     */
1990 
1991     ensSliceadaptorFetchByFeature(sla, feature, 0, &fslice);
1992 
1993     if (strand < 0)
1994         ensSliceFetchSliceinverted(fslice, &nslice);
1995     else
1996         nslice = ensSliceNewRef(fslice);
1997 
1998     ensSliceDel(&fslice);
1999 
2000     ensSliceProjectslice(nslice, slice, pss);
2001 
2002     ensSliceDel(&nslice);
2003 
2004     return ajTrue;
2005 }
2006 
2007 
2008 
2009 
2010 /* @func ensFeatureTransfer ***************************************************
2011 **
2012 ** Transfer an Ensembl Feature onto another Ensembl Slice.
2013 **
2014 ** @cc Bio::EnsEMBL::Feature::transfer
2015 ** @param [u] feature [EnsPFeature] Ensembl Feature
2016 ** @param [u] slice [EnsPSlice] Ensembl Slice
2017 **
2018 ** @return [EnsPFeature] Ensembl Feature or NULL
2019 **
2020 ** @release 6.2.0
2021 ** @@
2022 ** Returns a copy of this Feature, which has been shifted onto another Slice.
2023 **
2024 ** If the new Slice is in a different Coordinate System, the Feature is
2025 ** transformed first and then placed on the Slice.
2026 **
2027 ** If the Feature would be split across a Coordinate System boundary or mapped
2028 ** to a gap NULL will be returned instead.
2029 **
2030 ** If the Feature cannot be placed on the provided Slice because it maps to an
2031 ** entirely different Sequence Region, NULL will be returned instead.
2032 ******************************************************************************/
2033 
ensFeatureTransfer(EnsPFeature feature,EnsPSlice slice)2034 EnsPFeature ensFeatureTransfer(EnsPFeature feature, EnsPSlice slice)
2035 {
2036     ajint nfstart = 0;
2037     ajint nfend   = 0;
2038 
2039     const EnsPCoordsystem srccs = NULL;
2040     const EnsPCoordsystem trgcs = NULL;
2041 
2042     EnsPFeature nf = NULL;
2043 
2044     if (!feature)
2045     {
2046         ajDebug("ensFeatureTransfer requires an Ensembl Feature.\n");
2047 
2048         return NULL;
2049     }
2050 
2051     if (!slice)
2052     {
2053         ajDebug("ensFeatureTransfer requires an Ensembl Slice.\n");
2054 
2055         return NULL;
2056     }
2057 
2058     if (!feature->Slice)
2059     {
2060         ajDebug("ensFeatureTransfer requires an Ensembl Feature with "
2061                 "an Ensembl Slice attached.");
2062 
2063         return NULL;
2064     }
2065 
2066     srccs = ensSliceGetCoordsystemObject(feature->Slice);
2067     trgcs = ensSliceGetCoordsystemObject(slice);
2068 
2069     /*
2070     ** If the Coordinate System objects of Feature and Slice are identical,
2071     ** adjust only coordinates. In case they are not, the Feature needs
2072     ** transforming into the target Cordinate System first.
2073     */
2074 
2075     if (ensCoordsystemMatch(srccs, trgcs))
2076         nf = ensFeatureNewCpy(feature);
2077     else
2078     {
2079         nf = ensFeatureTransform(feature,
2080                                  ensCoordsystemGetName(trgcs),
2081                                  ensCoordsystemGetVersion(trgcs),
2082                                  slice);
2083 
2084         if (!nf)
2085         {
2086             ajDebug("ensFeatureTransfer got no Feature from "
2087                     "ensFeatureTransform.\n");
2088 
2089             return NULL;
2090         }
2091     }
2092 
2093     /*
2094     ** Discard Feature objects that were transformed to an entirely different
2095     ** Sequence Region than the one underlying the requested Slice.
2096     */
2097 
2098     if (!ensSeqregionMatch(ensSliceGetSeqregion(nf->Slice),
2099                            ensSliceGetSeqregion(slice)))
2100     {
2101         ajDebug("ensFeatureTransfer transformed Ensembl Feature %p onto "
2102                 "Sequence Region '%S:%S:%S', which is different from the "
2103                 "requested Ensembl Slice '%S:%S:%S'.\n",
2104                 nf,
2105                 ensSliceGetCoordsystemName(nf->Slice),
2106                 ensSliceGetCoordsystemVersion(nf->Slice),
2107                 ensSliceGetSeqregionName(nf->Slice),
2108                 ensSliceGetCoordsystemName(slice),
2109                 ensSliceGetCoordsystemVersion(slice),
2110                 ensSliceGetSeqregionName(slice));
2111 
2112         ensFeatureTrace(nf, 1);
2113 
2114         ensFeatureDel(&nf);
2115 
2116         return NULL;
2117     }
2118 
2119     /*
2120     ** Convert Feature coordinates from Slice to Sequence Region coordinates.
2121     ** NOTE: Instead of testing first, this implementation always converts,
2122     ** which should be faster.
2123     */
2124 
2125     nfstart = nf->Start;
2126     nfend   = nf->End;
2127 
2128     if (ensSliceGetStrand(nf->Slice) >= 0)
2129     {
2130         nf->Start = nfstart + ensSliceGetStart(nf->Slice) - 1;
2131         nf->End   = nfend   + ensSliceGetStart(nf->Slice) - 1;
2132     }
2133     else
2134     {
2135         nf->Start   = ensSliceGetEnd(nf->Slice) - nfend   + 1;
2136         nf->End     = ensSliceGetEnd(nf->Slice) - nfstart + 1;
2137         nf->Strand *= -1;
2138     }
2139 
2140     /*
2141     ** Convert Feature coordinates from Sequence Region to
2142     ** target Slice coordinates.
2143     */
2144 
2145     nfstart = nf->Start;
2146     nfend   = nf->End;
2147 
2148     if (ensSliceGetStrand(slice) >= 0)
2149     {
2150         nf->Start = nfstart - ensSliceGetStart(slice) + 1;
2151         nf->End   = nfend   - ensSliceGetStart(slice) + 1;
2152     }
2153     else
2154     {
2155         nf->Start   = ensSliceGetEnd(slice) - nfend   + 1;
2156         nf->End     = ensSliceGetEnd(slice) - nfstart + 1;
2157         nf->Strand *= -1;
2158     }
2159 
2160     ensFeatureSetSlice(nf, slice);
2161 
2162     return nf;
2163 }
2164 
2165 
2166 
2167 
2168 /* @func ensFeatureTransform **************************************************
2169 **
2170 ** Transform an Ensembl Feature into another Ensembl Coordinate System.
2171 **
2172 ** May simply return a reference copy
2173 **
2174 ** @cc Bio::EnsEMBL::Feature::transform
2175 ** @param [u] feature [EnsPFeature] Ensembl Feature
2176 ** @param [r] csname [const AjPStr] Ensembl Coordinate System name
2177 ** @param [rN] csversion [const AjPStr] Ensembl Coordinate System version
2178 ** @param [uN] slice [EnsPSlice] Ensembl Slice
2179 **
2180 ** @return [EnsPFeature] Ensembl Feature or NULL
2181 **
2182 ** @release 6.2.0
2183 ** @@
2184 ** Returns a copy of this Feature converted to a different Coordinate System.
2185 **
2186 ** The converted Feature will be placed on a Slice which spans an entire
2187 ** Sequence Region of the new Coordinate System. If the requested Coordinate
2188 ** System is the same Coordinate System it is simply placed on a Slice, which
2189 ** spans the entire Sequence Region as opposed to the original Slice, which may
2190 ** have only partially covered the Sequence Region.
2191 **
2192 ** If a Feature spans a (Sequence Region) boundary in the new
2193 ** Coordinate System, NULL will be returned instead.
2194 **
2195 ** For example, transforming an Exon in contig coordinates to one in
2196 ** chromosome coordinates will place the Exon on a Slice of an entire
2197 ** chromosome.
2198 ******************************************************************************/
2199 
ensFeatureTransform(EnsPFeature feature,const AjPStr csname,const AjPStr csversion,EnsPSlice slice)2200 EnsPFeature ensFeatureTransform(EnsPFeature feature,
2201                                 const AjPStr csname,
2202                                 const AjPStr csversion,
2203                                 EnsPSlice slice)
2204 {
2205     AjBool match = AJFALSE;
2206 
2207     AjIList iterator = NULL;
2208     AjPList pss      = NULL;
2209 
2210     EnsPCoordsystem cs = NULL;
2211 
2212     EnsPDatabaseadaptor dba = NULL;
2213 
2214     EnsPFeature nfeature = NULL;
2215 
2216     EnsPProjectionsegment ps = NULL;
2217 
2218     EnsPSlice       nslice = NULL;
2219     const EnsPSlice pslice = NULL;
2220     EnsPSliceadaptor sla   = NULL;
2221 
2222     if (!feature)
2223     {
2224         ajDebug("ensFeatureTransform requires an Ensembl Feature.\n");
2225 
2226         return NULL;
2227     }
2228 
2229     if (!csname)
2230     {
2231         ajDebug("ensFeatureTransform requires a Coordinate System name.\n");
2232 
2233         return NULL;
2234     }
2235 
2236     /* A Coordinate System version is not strictly required. */
2237 
2238     if (!feature->Slice)
2239     {
2240         ajWarn("ensFeatureTransform requires an Ensembl Feature with "
2241                "an Ensembl Slice attached to it.\n");
2242 
2243         return NULL;
2244     }
2245 
2246     /*
2247     ** Use the Ensembl Database Adaptor of the Slice as this Feature may not
2248     ** yet be stored in the database and may not have its own Adaptor.
2249     */
2250 
2251     sla = ensSliceGetAdaptor(feature->Slice);
2252 
2253     if (!sla)
2254     {
2255         ajWarn("ensFeatureTransform requires an Ensembl Feature with "
2256                "an Ensembl Slice Adaptor member attached to the "
2257                "Ensembl Slice member.\n");
2258 
2259         return NULL;
2260     }
2261 
2262     if (!ensSliceGetCoordsystemObject(feature->Slice))
2263     {
2264         ajWarn("ensFeatureTransform requires an Ensembl Feature with "
2265                "an Ensembl Coordinate System member attached to the "
2266                "Ensembl Slice member.\n");
2267 
2268         return NULL;
2269     }
2270 
2271     dba = ensSliceadaptorGetDatabaseadaptor(sla);
2272 
2273     ensCoordsystemadaptorFetchByName(
2274         ensRegistryGetCoordsystemadaptor(dba),
2275         csname,
2276         csversion,
2277         &cs);
2278 
2279     if (!cs)
2280         ajFatal("ensFeatureTransform cannot transform to an unknown "
2281                 "Ensembl Coordinate System '%S:%S'.", csname, csversion);
2282 
2283     /*
2284     ** If the Ensembl Feature is already in the requested Coordinate System,
2285     ** and on a regular Sequence Region Slice, we can simply return a copy
2286     ** of this Feature.
2287     */
2288 
2289     /*
2290     ** FIXME: Shouldn't this test also check for the correct Sequence Region
2291     ** length as the end point of the Slice? Although coordinates would not be
2292     ** affected in case a Slice was shorter at its end, shouldn't the Slice
2293     ** cover the entire Sequence Region for consistency?
2294     ** ensSliceadaptorFetchBySeqregionIdentifier below would return a Slice
2295     ** covering the full Sequence Region.
2296     */
2297 
2298     if (ensCoordsystemMatch(cs, ensSliceGetCoordsystemObject(feature->Slice))
2299         && (ensSliceGetStart(feature->Slice) == 1)
2300         && (ensSliceGetStrand(feature->Slice) >= 0))
2301     {
2302         nfeature = ensFeatureNewRef(feature);
2303 
2304         ensCoordsystemDel(&cs);
2305 
2306         return nfeature;
2307     }
2308 
2309     /*
2310     ** If a Coordinate System different from the Feature Coordinate System was
2311     ** requested, project the Feature into this other Coordinate System, but
2312     ** place the Feature only, if it projects in one piece i.e does not span
2313     ** Sequence Region boundaries.
2314     */
2315 
2316     pss = ajListNew();
2317 
2318     if (slice)
2319         ensFeatureProjectslice(feature, slice, pss);
2320     else
2321         ensFeatureProject(feature, csname, csversion, pss);
2322 
2323     /*
2324     ** For Ensembl Feature objects that project more than once,
2325     ** an Ensembl Slice should be specified.
2326     */
2327 
2328     if (ajListGetLength(pss) <= 1)
2329     {
2330         ajListPeekFirst(pss, (void **) &ps);
2331 
2332         if (ps)
2333             match = ajTrue;
2334     }
2335     else if (slice)
2336     {
2337         iterator = ajListIterNew(pss);
2338 
2339         while (!ajListIterDone(iterator))
2340         {
2341             ps = (EnsPProjectionsegment) ajListIterGet(iterator);
2342 
2343             pslice = ensProjectionsegmentGetTargetSlice(ps);
2344 
2345             if (ensSliceGetSeqregionIdentifier(pslice) ==
2346                 ensSliceGetSeqregionIdentifier(slice))
2347             {
2348                 match = ajTrue;
2349 
2350                 break;
2351             }
2352         }
2353 
2354         ajListIterDel(&iterator);
2355     }
2356 
2357     if (match)
2358     {
2359         ensSliceadaptorFetchBySeqregionIdentifier(
2360             sla,
2361             ensSliceGetSeqregionIdentifier(pslice),
2362             0,
2363             0,
2364             1,
2365             &nslice);
2366 
2367         nfeature = ensFeatureNewCpy(feature);
2368 
2369         nfeature->Start  = ensSliceGetStart(pslice);
2370         nfeature->End    = ensSliceGetEnd(pslice);
2371         nfeature->Strand = (feature->Strand == 0)
2372             ? 0 : ensSliceGetStrand(pslice);
2373 
2374         ensFeatureSetSlice(nfeature, nslice);
2375 
2376         ensSliceDel(&nslice);
2377     }
2378 
2379     if ((match == ajFalse) && (ajListGetLength(pss) > 1))
2380         ajWarn("ensFeatureTransform got %Lu Ensembl Projection Segment "
2381                "objects, but no Ensembl Slice was specified.",
2382                ajListGetLength(pss));
2383 
2384     while (ajListPop(pss, (void **) &ps))
2385         ensProjectionsegmentDel(&ps);
2386 
2387     ajListFree(&pss);
2388 
2389     ensCoordsystemDel(&cs);
2390 
2391     return nfeature;
2392 }
2393 
2394 
2395 
2396 
2397 /* @section matching **********************************************************
2398 **
2399 ** Functions for matching Ensembl Feature objects
2400 **
2401 ** @fdata [EnsPFeature]
2402 **
2403 ** @nam3rule Match      Test Ensembl Feature objects for identity
2404 ** @nam3rule Overlap    Test Ensembl Feature objects for overlap
2405 ** @nam3rule Similarity Test Ensembl Feature objects for similarity
2406 **
2407 ** @argrule * feature1 [const EnsPFeature] Ensembl Feature
2408 ** @argrule * feature2 [const EnsPFeature] Ensembl Feature
2409 **
2410 ** @valrule * [AjBool] True on success
2411 **
2412 ** @fcategory use
2413 ******************************************************************************/
2414 
2415 
2416 
2417 
2418 /* @func ensFeatureMatch ******************************************************
2419 **
2420 ** Test two Ensembl Feature objects for identity.
2421 **
2422 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature
2423 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature
2424 **
2425 ** @return [AjBool] ajTrue if the Ensembl Feature objects are equal
2426 **
2427 ** @release 6.3.0
2428 ** @@
2429 ** The comparison is based on an initial pointer equality test and if that
2430 ** fails, a case-sensitive string comparison of the sequence name and
2431 ** comparisons of other members are performed.
2432 ******************************************************************************/
2433 
ensFeatureMatch(const EnsPFeature feature1,const EnsPFeature feature2)2434 AjBool ensFeatureMatch(const EnsPFeature feature1,
2435                        const EnsPFeature feature2)
2436 {
2437     if (!feature1)
2438         return ajFalse;
2439 
2440     if (!feature2)
2441         return ajFalse;
2442 
2443     if (feature1 == feature2)
2444         return ajTrue;
2445 
2446     /* Ensembl Analysis objects are optional. */
2447 
2448     if ((feature1->Analysis || feature2->Analysis)
2449         && (!ensAnalysisMatch(feature1->Analysis, feature2->Analysis)))
2450         return ajFalse;
2451 
2452     if (!ensSliceMatch(feature1->Slice, feature2->Slice))
2453         return ajFalse;
2454 
2455     /* Sequence names are optional. */
2456 
2457     if ((feature1->Sequencename || feature2->Sequencename)
2458         && (!ajStrMatchS(feature1->Sequencename, feature2->Sequencename)))
2459         return ajFalse;
2460 
2461     if (feature1->Start != feature2->Start)
2462         return ajFalse;
2463 
2464     if (feature1->End != feature2->End)
2465         return ajFalse;
2466 
2467     if (feature1->Strand != feature2->Strand)
2468         return ajFalse;
2469 
2470     return ajTrue;
2471 }
2472 
2473 
2474 
2475 
2476 /* @func ensFeatureOverlap ****************************************************
2477 **
2478 ** Tests two Ensembl Feature objects for overlap.
2479 **
2480 ** @cc Bio::EnsEMBL::Feature::overlaps
2481 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature
2482 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature
2483 **
2484 ** @return [AjBool] ajTrue if the Ensembl Feature objects overlap on the same
2485 **                  Ensembl Sequence Region, ajFalse otherwise
2486 **
2487 ** @release 6.2.0
2488 ** @@
2489 ******************************************************************************/
2490 
ensFeatureOverlap(const EnsPFeature feature1,const EnsPFeature feature2)2491 AjBool ensFeatureOverlap(const EnsPFeature feature1,
2492                          const EnsPFeature feature2)
2493 {
2494     AjPStr name1 = NULL;
2495     AjPStr name2 = NULL;
2496 
2497     if (!feature1)
2498         return ajFalse;
2499 
2500     if (!feature2)
2501         return ajFalse;
2502 
2503     name1 = ajStrNew();
2504     name2 = ajStrNew();
2505 
2506     ensFeatureFetchSequencename(feature1, &name1);
2507     ensFeatureFetchSequencename(feature2, &name2);
2508 
2509     if ((name1 && name2) && (!ajStrMatchCaseS(name1, name2)))
2510     {
2511         ajDebug("ensFeatureOverlap got Ensembl Feature objects on different "
2512                 "Ensembl Sequence Region objects.\n");
2513 
2514         ajStrDel(&name1);
2515         ajStrDel(&name2);
2516 
2517         return ajFalse;
2518     }
2519 
2520     ajStrDel(&name1);
2521     ajStrDel(&name2);
2522 
2523     return ((ensFeatureGetSeqregionEnd(feature1) >=
2524              ensFeatureGetSeqregionStart(feature2))
2525             &&
2526             (ensFeatureGetSeqregionStart(feature1) <=
2527              ensFeatureGetSeqregionEnd(feature2)));
2528 }
2529 
2530 
2531 
2532 
2533 /* @func ensFeatureSimilarity *************************************************
2534 **
2535 ** Test Ensembl Feature objects for similarity.
2536 **
2537 ** @cc Bio::EnsEMBL::Feature::equals
2538 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature
2539 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature
2540 **
2541 ** @return [AjBool] ajTrue if the Ensembl Feature objects are equal
2542 **
2543 ** @release 6.4.0
2544 ** @@
2545 ** NOTE: This function is similar to the Bio::EnsEMBL::Feature::equals method,
2546 ** but not identical.
2547 ** The comparison is based on an initial pointer equality test and if that
2548 ** fails, the Ensembl Slice objects are compared for similarity.
2549 ** The Ensembl Feature coordinates are compared as absolute Ensembl Sequence
2550 ** Region coordinates. If Ensembl Analysis objects have been set, they are
2551 ** matched. If sequence names have been set, they are compared
2552 ** in a case-sensitive manner.
2553 ******************************************************************************/
2554 
ensFeatureSimilarity(const EnsPFeature feature1,const EnsPFeature feature2)2555 AjBool ensFeatureSimilarity(const EnsPFeature feature1,
2556                             const EnsPFeature feature2)
2557 {
2558     if (!feature1)
2559         return ajFalse;
2560 
2561     if (!feature2)
2562         return ajFalse;
2563 
2564     if (feature1 == feature2)
2565         return ajTrue;
2566 
2567     /* Ensembl Analysis objects are optional. */
2568 
2569     if ((feature1->Analysis || feature2->Analysis)
2570         && (!ensAnalysisMatch(feature1->Analysis, feature2->Analysis)))
2571         return ajFalse;
2572 
2573     if (!ensSliceSimilarity(feature1->Slice, feature2->Slice))
2574         return ajFalse;
2575 
2576     /* Sequence names are optional. */
2577 
2578     if ((feature1->Sequencename || feature2->Sequencename)
2579         && (!ajStrMatchS(feature1->Sequencename, feature2->Sequencename)))
2580         return ajFalse;
2581 
2582     /* Compare absolute Ensembl Sequence Region coordinates. */
2583 
2584     if (ensFeatureGetSeqregionStart(feature1) !=
2585         ensFeatureGetSeqregionStart(feature2))
2586         return ajFalse;
2587 
2588     if (ensFeatureGetSeqregionEnd(feature1) !=
2589         ensFeatureGetSeqregionEnd(feature2))
2590         return ajFalse;
2591 
2592     if (ensFeatureGetSeqregionStrand(feature1) !=
2593         ensFeatureGetSeqregionStrand(feature2))
2594         return ajFalse;
2595 
2596     return ajTrue;
2597 }
2598 
2599 
2600 
2601 
2602 /* @section comparing *********************************************************
2603 **
2604 ** Functions for comparing Ensembl Feature objects
2605 **
2606 ** @fdata [EnsPFeature]
2607 **
2608 ** @nam3rule Compare    Compare two Ensembl Feature objects
2609 ** @nam4rule End        Compare by Ensembl Feature end members
2610 ** @nam4rule Start      Compare by Ensembl Feature start members
2611 ** @nam5rule Ascending  Compare in ascending order
2612 ** @nam5rule Descending Compare in descending order
2613 **
2614 ** @argrule * feature1 [const EnsPFeature] Ensembl Feature 1
2615 ** @argrule * feature2 [const EnsPFeature] Ensembl Feature 2
2616 **
2617 ** @valrule * [int] The comparison function returns an integer less than,
2618 **                  equal to, or greater than zero if the first argument is
2619 **                  considered to be respectively less than, equal to, or
2620 **                  greater than the second.
2621 **
2622 ** @fcategory use
2623 ******************************************************************************/
2624 
2625 
2626 
2627 
2628 /* @func ensFeatureCompareEndAscending ****************************************
2629 **
2630 ** AJAX List of Ensembl Feature objects comparison function to sort by
2631 ** end member in ascending order.
2632 **
2633 ** Ensembl Feature objects based on Ensembl Slice objects sort before
2634 ** Ensembl Feature objects based on sequence names.
2635 ** Ensembl Feature objects without Ensembl Slice objects or sequence names
2636 ** sort towards the end of the AJAX List.
2637 **
2638 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature 1
2639 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature 2
2640 ** @see ajListSort
2641 **
2642 ** @return [int] The comparison function returns an integer less than,
2643 **               equal to, or greater than zero if the first argument is
2644 **               considered to be respectively less than, equal to, or
2645 **               greater than the second.
2646 **
2647 ** @release 6.3.0
2648 ** @@
2649 ******************************************************************************/
2650 
ensFeatureCompareEndAscending(const EnsPFeature feature1,const EnsPFeature feature2)2651 int ensFeatureCompareEndAscending(const EnsPFeature feature1,
2652                                   const EnsPFeature feature2)
2653 {
2654     int result = 0;
2655 
2656     /* Sort empty values towards the end of the AJAX List. */
2657 
2658     if (feature1 && (!feature2))
2659         return -1;
2660 
2661     if ((!feature1) && (!feature2))
2662         return 0;
2663 
2664     if ((!feature1) && feature2)
2665         return +1;
2666 
2667     /*
2668     ** Ensembl Feature objects based on Ensembl Slices sort before
2669     ** Ensembl Feature objects based on sequence names.
2670     ** For Ensembl Feature objects based on identical Slice objects or
2671     ** sequence names evaluate start coordinates.
2672     */
2673 
2674     if (feature1->Slice && feature2->Sequencename)
2675         return -1;
2676 
2677     if (feature1->Slice && feature2->Slice &&
2678         (result = ensSliceCompareIdentifierAscending(feature1->Slice,
2679                                                      feature2->Slice)))
2680         return result;
2681 
2682     if (feature1->Sequencename && feature2->Sequencename &&
2683         (result = ajStrCmpS(feature1->Sequencename,
2684                             feature2->Sequencename)))
2685         return result;
2686 
2687     if (feature1->Sequencename && feature2->Slice)
2688         return +1;
2689 
2690     /* No decision yet, evaluate Feature end coordinates. */
2691 
2692     if (feature1->End < feature2->End)
2693         return -1;
2694 
2695     if (feature1->End > feature2->End)
2696         return +1;
2697 
2698 #if AJFALSE
2699     /* No decision yet, evaluate Feature start coordinates. */
2700 
2701     if (feature1->Start < feature2->Start)
2702         return -1;
2703 
2704     if (feature1->Start > feature2->Start)
2705         return +1;
2706 #endif /* AJFALSE */
2707 
2708     return 0;
2709 }
2710 
2711 
2712 
2713 
2714 /* @func ensFeatureCompareEndDescending ***************************************
2715 **
2716 ** AJAX List of Ensembl Feature objects comparison function to sort by
2717 ** end member in descending order.
2718 **
2719 ** Ensembl Feature objects based on Ensembl Slice objects sort before
2720 ** Ensembl Feature objects based on sequence names.
2721 ** Ensembl Feature objects without Ensembl Slice objects or sequence names
2722 ** sort towards the end of the AJAX List.
2723 **
2724 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature 1
2725 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature 2
2726 ** @see ajListSort
2727 **
2728 ** @return [int] The comparison function returns an integer less than,
2729 **               equal to, or greater than zero if the first argument is
2730 **               considered to be respectively less than, equal to, or
2731 **               greater than the second.
2732 **
2733 ** @release 6.3.0
2734 ** @@
2735 ******************************************************************************/
2736 
ensFeatureCompareEndDescending(const EnsPFeature feature1,const EnsPFeature feature2)2737 int ensFeatureCompareEndDescending(const EnsPFeature feature1,
2738                                    const EnsPFeature feature2)
2739 {
2740     int result = 0;
2741 
2742     /* Sort empty values towards the end of the AJAX List. */
2743 
2744     if (feature1 && (!feature2))
2745         return -1;
2746 
2747     if ((!feature1) && (!feature2))
2748         return 0;
2749 
2750     if ((!feature1) && feature2)
2751         return +1;
2752 
2753     /*
2754     ** Ensembl Feature objects based on Ensembl Slice objects sort before
2755     ** Ensembl Feature objects based on sequence names.
2756     ** For Ensembl Feature objects based on identical Slice objects or
2757     ** sequence names evaluate start coordinates.
2758     */
2759 
2760     if (feature1->Slice && feature2->Sequencename)
2761         return -1;
2762 
2763     if (feature1->Slice && feature2->Slice &&
2764         (result = ensSliceCompareIdentifierAscending(feature1->Slice,
2765                                                      feature2->Slice)))
2766         return result;
2767 
2768     if (feature1->Sequencename && feature2->Sequencename &&
2769         (result = ajStrCmpS(feature1->Sequencename,
2770                             feature2->Sequencename)))
2771         return result;
2772 
2773     if (feature1->Sequencename && feature2->Slice)
2774         return +1;
2775 
2776     /* No decision yet, evaluate Feature end coordinates. */
2777 
2778     if (feature1->End < feature2->End)
2779         return +1;
2780 
2781     if (feature1->End < feature2->End)
2782         return -1;
2783 
2784 #if AJFALSE
2785     /* No decision yet, evaluate Feature start coordinates. */
2786 
2787     if (feature1->Start < feature2->Start)
2788         return +1;
2789 
2790     if (feature1->Start < feature2->Start)
2791         return -1;
2792 #endif /* AJFALSE */
2793 
2794     return 0;
2795 }
2796 
2797 
2798 
2799 
2800 /* @func ensFeatureCompareStartAscending **************************************
2801 **
2802 ** AJAX List of Ensembl Feature objects comparison function to sort by
2803 ** start member in ascending order.
2804 **
2805 ** Ensembl Feature objects based on Ensembl Slice objects sort before
2806 ** Ensembl Feature objects based on sequence names.
2807 ** Ensembl Feature objects without Ensembl Slice objects or sequence names
2808 ** sort towards the end of the AJAX List.
2809 **
2810 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature 1
2811 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature 2
2812 ** @see ajListSort
2813 **
2814 ** @return [int] The comparison function returns an integer less than,
2815 **               equal to, or greater than zero if the first argument is
2816 **               considered to be respectively less than, equal to, or
2817 **               greater than the second.
2818 **
2819 ** @release 6.3.0
2820 ** @@
2821 ******************************************************************************/
2822 
ensFeatureCompareStartAscending(const EnsPFeature feature1,const EnsPFeature feature2)2823 int ensFeatureCompareStartAscending(const EnsPFeature feature1,
2824                                     const EnsPFeature feature2)
2825 {
2826     int result = 0;
2827 
2828     /* Sort empty values towards the end of the AJAX List. */
2829 
2830     if (feature1 && (!feature2))
2831         return -1;
2832 
2833     if ((!feature1) && (!feature2))
2834         return 0;
2835 
2836     if ((!feature1) && feature2)
2837         return +1;
2838 
2839     /*
2840     ** Ensembl Feature objects based on Ensembl Slices sort before
2841     ** Ensembl Feature objects based on sequence names.
2842     ** For Ensembl Feature objects based on identical Slice objects or
2843     ** sequence names evaluate start coordinates.
2844     */
2845 
2846     if (feature1->Slice && feature2->Sequencename)
2847         return -1;
2848 
2849     if (feature1->Slice && feature2->Slice &&
2850         (result = ensSliceCompareIdentifierAscending(feature1->Slice,
2851                                                      feature2->Slice)))
2852         return result;
2853 
2854     if (feature1->Sequencename && feature2->Sequencename &&
2855         (result = ajStrCmpS(feature1->Sequencename,
2856                             feature2->Sequencename)))
2857         return result;
2858 
2859     if (feature1->Sequencename && feature2->Slice)
2860         return +1;
2861 
2862     /* No decision yet, evaluate Feature start coordinates. */
2863 
2864     if (feature1->Start < feature2->Start)
2865         return -1;
2866 
2867     if (feature1->Start > feature2->Start)
2868         return +1;
2869 
2870 #if AJFALSE
2871     /* No decision yet, evaluate Feature end coordinates. */
2872 
2873     if (feature1->End < feature2->End)
2874         return -1;
2875 
2876     if (feature1->End > feature2->End)
2877         return +1;
2878 #endif /* AJFALSE */
2879 
2880     return 0;
2881 }
2882 
2883 
2884 
2885 
2886 /* @func ensFeatureCompareStartDescending *************************************
2887 **
2888 ** AJAX List of Ensembl Feature objects comparison function to sort by
2889 ** start member in descending order.
2890 **
2891 ** Ensembl Feature objects based on Ensembl Slice objects sort before
2892 ** Ensembl Feature objects based on sequence names.
2893 ** Ensembl Feature objects without Ensembl Slice objects or sequence names
2894 ** sort towards the end of the AJAX List.
2895 **
2896 ** @param [r] feature1 [const EnsPFeature] Ensembl Feature 1
2897 ** @param [r] feature2 [const EnsPFeature] Ensembl Feature 2
2898 ** @see ajListSort
2899 **
2900 ** @return [int] The comparison function returns an integer less than,
2901 **               equal to, or greater than zero if the first argument is
2902 **               considered to be respectively less than, equal to, or
2903 **               greater than the second.
2904 **
2905 ** @release 6.3.0
2906 ** @@
2907 ******************************************************************************/
2908 
ensFeatureCompareStartDescending(const EnsPFeature feature1,const EnsPFeature feature2)2909 int ensFeatureCompareStartDescending(const EnsPFeature feature1,
2910                                      const EnsPFeature feature2)
2911 {
2912     int result = 0;
2913 
2914     /* Sort empty values towards the end of the AJAX List. */
2915 
2916     if (feature1 && (!feature2))
2917         return -1;
2918 
2919     if ((!feature1) && (!feature2))
2920         return 0;
2921 
2922     if ((!feature1) && feature2)
2923         return +1;
2924 
2925     /*
2926     ** Ensembl Feature objects based on Ensembl Slice objects sort before
2927     ** Ensembl Feature objects based on sequence names.
2928     ** For Ensembl Feature objects based on identical Slice objects or
2929     ** sequence names evaluate start coordinates.
2930     */
2931 
2932     if (feature1->Slice && feature2->Sequencename)
2933         return -1;
2934 
2935     if (feature1->Slice && feature2->Slice &&
2936         (result = ensSliceCompareIdentifierAscending(feature1->Slice,
2937                                                      feature2->Slice)))
2938         return result;
2939 
2940     if (feature1->Sequencename && feature2->Sequencename &&
2941         (result = ajStrCmpS(feature1->Sequencename,
2942                             feature2->Sequencename)))
2943         return result;
2944 
2945     if (feature1->Sequencename && feature2->Slice)
2946         return +1;
2947 
2948     /* No decision yet, evaluate Feature start coordinates. */
2949 
2950     if (feature1->Start < feature2->Start)
2951         return +1;
2952 
2953     if (feature1->Start > feature2->Start)
2954         return -1;
2955 
2956 #if AJFALSE
2957     /* No decision yet, evaluate Feature end coordinates. */
2958 
2959     if (feature1->End < feature2->End)
2960         return +1;
2961 
2962     if (feature1->End > feature2->End)
2963         return -1;
2964 #endif /* AJFALSE */
2965 
2966     return 0;
2967 }
2968 
2969 
2970 
2971 
2972 /* @funcstatic listFeatureCompareEndAscending *********************************
2973 **
2974 ** AJAX List of Ensembl Feature objects comparison function to sort by
2975 ** end coordinate in ascending order.
2976 **
2977 ** @param [r] item1 [const void*] Ensembl Feature address 1
2978 ** @param [r] item2 [const void*] Ensembl Feature address 2
2979 ** @see ajListSort
2980 **
2981 ** @return [int] The comparison function returns an integer less than,
2982 **               equal to, or greater than zero if the first argument is
2983 **               considered to be respectively less than, equal to, or
2984 **               greater than the second.
2985 **
2986 ** @release 6.4.0
2987 ** @@
2988 ******************************************************************************/
2989 
listFeatureCompareEndAscending(const void * item1,const void * item2)2990 static int listFeatureCompareEndAscending(
2991     const void *item1,
2992     const void *item2)
2993 {
2994     EnsPFeature feature1 = *(EnsOFeature *const *) item1;
2995     EnsPFeature feature2 = *(EnsOFeature *const *) item2;
2996 
2997 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
2998     if (ajDebugTest("listFeatureCompareEndAscending"))
2999     {
3000         ajDebug("listFeatureCompareEndAscending\n"
3001                 "  feature1 %p\n"
3002                 "  feature2 %p\n",
3003                 feature1,
3004                 feature2);
3005 
3006         ensFeatureTrace(feature1, 1);
3007         ensFeatureTrace(feature2, 1);
3008     }
3009 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3010 
3011     /* Sort empty values towards the end of the AJAX List. */
3012 
3013     if (feature1 && (!feature2))
3014         return -1;
3015 
3016     if ((!feature1) && (!feature2))
3017         return 0;
3018 
3019     if ((!feature1) && feature2)
3020         return +1;
3021 
3022     return ensFeatureCompareEndAscending(feature1, feature2);
3023 }
3024 
3025 
3026 
3027 
3028 /* @funcstatic listFeatureCompareEndDescending ********************************
3029 **
3030 ** AJAX List of Ensembl Feature objects comparison function to sort by
3031 ** end coordinate in descending order.
3032 **
3033 ** @param [r] item1 [const void*] Ensembl Feature address 1
3034 ** @param [r] item2 [const void*] Ensembl Feature address 2
3035 ** @see ajListSort
3036 **
3037 ** @return [int] The comparison function returns an integer less than,
3038 **               equal to, or greater than zero if the first argument is
3039 **               considered to be respectively less than, equal to, or
3040 **               greater than the second.
3041 **
3042 ** @release 6.4.0
3043 ** @@
3044 ******************************************************************************/
3045 
listFeatureCompareEndDescending(const void * item1,const void * item2)3046 static int listFeatureCompareEndDescending(
3047     const void *item1,
3048     const void *item2)
3049 {
3050     EnsPFeature feature1 = *(EnsOFeature *const *) item1;
3051     EnsPFeature feature2 = *(EnsOFeature *const *) item2;
3052 
3053 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3054     if (ajDebugTest("listFeatureCompareEndDescending"))
3055     {
3056         ajDebug("listFeatureCompareEndDescending\n"
3057                 "  feature1 %p\n"
3058                 "  feature2 %p\n",
3059                 feature1,
3060                 feature2);
3061 
3062         ensFeatureTrace(feature1, 1);
3063         ensFeatureTrace(feature2, 1);
3064     }
3065 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3066 
3067     /* Sort empty values towards the end of the AJAX List. */
3068 
3069     if (feature1 && (!feature2))
3070         return -1;
3071 
3072     if ((!feature1) && (!feature2))
3073         return 0;
3074 
3075     if ((!feature1) && feature2)
3076         return +1;
3077 
3078     return ensFeatureCompareEndDescending(feature1, feature2);
3079 }
3080 
3081 
3082 
3083 
3084 /* @funcstatic listFeatureCompareStartAscending *******************************
3085 **
3086 ** AJAX List of Ensembl Feature objects comparison function to sort by
3087 ** start coordinate in ascending order.
3088 **
3089 ** @param [r] item1 [const void*] Ensembl Feature address 1
3090 ** @param [r] item2 [const void*] Ensembl Feature address 2
3091 ** @see ajListSort
3092 **
3093 ** @return [int] The comparison function returns an integer less than,
3094 **               equal to, or greater than zero if the first argument is
3095 **               considered to be respectively less than, equal to, or
3096 **               greater than the second.
3097 **
3098 ** @release 6.4.0
3099 ** @@
3100 ******************************************************************************/
3101 
listFeatureCompareStartAscending(const void * item1,const void * item2)3102 static int listFeatureCompareStartAscending(
3103     const void *item1,
3104     const void *item2)
3105 {
3106     EnsPFeature feature1 = *(EnsOFeature *const *) item1;
3107     EnsPFeature feature2 = *(EnsOFeature *const *) item2;
3108 
3109 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3110     if (ajDebugTest("listFeatureCompareStartAscending"))
3111     {
3112         ajDebug("listFeatureCompareStartAscending\n"
3113                 "  feature1 %p\n"
3114                 "  feature2 %p\n",
3115                 feature1,
3116                 feature2);
3117 
3118         ensFeatureTrace(feature1, 1);
3119         ensFeatureTrace(feature2, 1);
3120     }
3121 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3122 
3123     /* Sort empty values towards the end of the AJAX List. */
3124 
3125     if (feature1 && (!feature2))
3126         return -1;
3127 
3128     if ((!feature1) && (!feature2))
3129         return 0;
3130 
3131     if ((!feature1) && feature2)
3132         return +1;
3133 
3134     return ensFeatureCompareStartAscending(feature1, feature2);
3135 }
3136 
3137 
3138 
3139 
3140 /* @funcstatic listFeatureCompareStartDescending ******************************
3141 **
3142 ** AJAX List of Ensembl Feature objects comparison function to sort by
3143 ** start coordinate in descending order.
3144 **
3145 ** @param [r] item1 [const void*] Ensembl Feature address 1
3146 ** @param [r] item2 [const void*] Ensembl Feature address 2
3147 ** @see ajListSort
3148 **
3149 ** @return [int] The comparison function returns an integer less than,
3150 **               equal to, or greater than zero if the first argument is
3151 **               considered to be respectively less than, equal to, or
3152 **               greater than the second.
3153 **
3154 ** @release 6.4.0
3155 ** @@
3156 ******************************************************************************/
3157 
listFeatureCompareStartDescending(const void * item1,const void * item2)3158 static int listFeatureCompareStartDescending(
3159     const void *item1,
3160     const void *item2)
3161 {
3162     EnsPFeature feature1 = *(EnsOFeature *const *) item1;
3163     EnsPFeature feature2 = *(EnsOFeature *const *) item2;
3164 
3165 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3166     if (ajDebugTest("listFeatureCompareStartDescending"))
3167     {
3168         ajDebug("listFeatureCompareStartDescending\n"
3169                 "  feature1 %p\n"
3170                 "  feature2 %p\n",
3171                 feature1,
3172                 feature2);
3173 
3174         ensFeatureTrace(feature1, 1);
3175         ensFeatureTrace(feature2, 1);
3176     }
3177 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3178 
3179     /* Sort empty values towards the end of the AJAX List. */
3180 
3181     if (feature1 && (!feature2))
3182         return -1;
3183 
3184     if ((!feature1) && (!feature2))
3185         return 0;
3186 
3187     if ((!feature1) && feature2)
3188         return +1;
3189 
3190     return ensFeatureCompareStartDescending(feature1, feature2);
3191 }
3192 
3193 
3194 
3195 
3196 /* @datasection [AjPList] AJAX List *******************************************
3197 **
3198 ** @nam2rule List Functions for manipulating AJAX List objects
3199 **
3200 ******************************************************************************/
3201 
3202 
3203 
3204 
3205 /* @section list **************************************************************
3206 **
3207 ** Functions for manipulating AJAX List objects.
3208 **
3209 ** @fdata [AjPList]
3210 **
3211 ** @nam3rule Feature Functions for manipulating AJAX List objects of
3212 ** Ensembl Feature objects
3213 ** @nam4rule Sort       Sort functions
3214 ** @nam5rule End        Sort by Ensembl Feature end member
3215 ** @nam5rule Start      Sort by Ensembl Feature start member
3216 ** @nam6rule Ascending  Sort in ascending order
3217 ** @nam6rule Descending Sort in descending order
3218 **
3219 ** @argrule * features [AjPList]
3220 ** AJAX List of Ensembl Feature objects
3221 **
3222 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
3223 **
3224 ** @fcategory misc
3225 ******************************************************************************/
3226 
3227 
3228 
3229 
3230 /* @func ensListFeatureSortEndAscending ***************************************
3231 **
3232 ** Sort an AJAX List of Ensembl Feature objects by their end member in
3233 ** ascending order.
3234 **
3235 ** @param [u] features [AjPList] AJAX List of Ensembl Feature objects
3236 ** @see ensFeatureCompareEndAscending
3237 **
3238 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3239 **
3240 ** @release 6.4.0
3241 ** @@
3242 ******************************************************************************/
3243 
ensListFeatureSortEndAscending(AjPList features)3244 AjBool ensListFeatureSortEndAscending(AjPList features)
3245 {
3246     if (!features)
3247         return ajFalse;
3248 
3249     ajListSortTwo(features,
3250                   &listFeatureCompareEndAscending,
3251                   &listFeatureCompareStartAscending);
3252 
3253     return ajTrue;
3254 }
3255 
3256 
3257 
3258 
3259 /* @func ensListFeatureSortEndDescending **************************************
3260 **
3261 ** Sort an AJAX List of Ensembl Feature objects by their end member in
3262 ** descending order.
3263 **
3264 ** @param [u] features [AjPList] AJAX List of Ensembl Feature objects
3265 ** @see ensFeatureCompareEndDescending
3266 **
3267 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3268 **
3269 ** @release 6.4.0
3270 ** @@
3271 ******************************************************************************/
3272 
ensListFeatureSortEndDescending(AjPList features)3273 AjBool ensListFeatureSortEndDescending(AjPList features)
3274 {
3275     if (!features)
3276         return ajFalse;
3277 
3278     ajListSortTwo(features,
3279                   &listFeatureCompareEndDescending,
3280                   &listFeatureCompareStartDescending);
3281 
3282     return ajTrue;
3283 }
3284 
3285 
3286 
3287 
3288 /* @func ensListFeatureSortStartAscending *************************************
3289 **
3290 ** Sort an AJAX List of Ensembl Feature objects by their start member in
3291 ** ascending order.
3292 **
3293 ** @param [u] features [AjPList] AJAX List of Ensembl Feature objects
3294 ** @see ensFeatureCompareStartAscending
3295 **
3296 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3297 **
3298 ** @release 6.4.0
3299 ** @@
3300 ******************************************************************************/
3301 
ensListFeatureSortStartAscending(AjPList features)3302 AjBool ensListFeatureSortStartAscending(AjPList features)
3303 {
3304     if (!features)
3305         return ajFalse;
3306 
3307     ajListSortTwo(features,
3308                   &listFeatureCompareStartAscending,
3309                   &listFeatureCompareEndAscending);
3310 
3311     return ajTrue;
3312 }
3313 
3314 
3315 
3316 
3317 /* @func ensListFeatureSortStartDescending ************************************
3318 **
3319 ** Sort an AJAX List of Ensembl Feature objects by their start member in
3320 ** descending order.
3321 **
3322 ** @param [u] features [AjPList] AJAX List of Ensembl Feature objects
3323 ** @see ensFeatureCompareStartDescending
3324 **
3325 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3326 **
3327 ** @release 6.4.0
3328 ** @@
3329 ******************************************************************************/
3330 
ensListFeatureSortStartDescending(AjPList features)3331 AjBool ensListFeatureSortStartDescending(AjPList features)
3332 {
3333     if (!features)
3334         return ajFalse;
3335 
3336     ajListSortTwo(features,
3337                   &listFeatureCompareStartDescending,
3338                   &listFeatureCompareEndDescending);
3339 
3340     return ajTrue;
3341 }
3342 
3343 
3344 
3345 
3346 /* @datasection [EnsPFeatureadaptor] Ensembl Feature Adaptor ******************
3347 **
3348 ** @nam2rule Featureadaptor Functions for manipulating
3349 ** Ensembl Feature Adaptor objects
3350 **
3351 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor
3352 ** @cc CVS Revision: 1.119
3353 ** @cc CVS Tag: branch-ensembl-68
3354 **
3355 ******************************************************************************/
3356 
3357 
3358 
3359 
3360 /* @section constructors ******************************************************
3361 **
3362 ** All constructors return a new Ensembl Feature Adaptor by pointer.
3363 ** It is the responsibility of the user to first destroy any previous
3364 ** Feature Adaptor. The target pointer does not need to be initialised to
3365 ** NULL, but it is good programming practice to do so anyway.
3366 **
3367 ** @fdata [EnsPFeatureadaptor]
3368 **
3369 ** @nam3rule New Constructor
3370 **
3371 ** @argrule New dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
3372 ** @argrule New Ptablenames [const char* const*] SQL table name array
3373 ** @argrule New Pcolumnnames [const char* const*] SQL column name aray
3374 ** @argrule New leftjoins [const EnsPBaseadaptorLeftjoin]
3375 ** SQL LEFT JOIN condition array
3376 ** @argrule New defaultcondition [const char*] SQL SELECT default condition
3377 ** @argrule New finalcondition [const char*] SQL SELECT final condition
3378 ** @argrule New Fstatement [AjBool function] Statement function address
3379 ** @argrule New Fread [void* function] Read function address
3380 ** @argrule New Freference [void* function] Reference function address
3381 ** @argrule New Fwrite [AjBool function] Write function
3382 ** @argrule New Fdelete [void function] Delete function address
3383 ** @argrule New Fsize [size_t function] Size function address
3384 ** @argrule New Fgetfeature [EnsPFeature function] Get Feature function address
3385 ** @argrule New label [const char*] Ensembl Cache label
3386 **
3387 ** @valrule * [EnsPFeatureadaptor] Ensembl Feature Adaptor or NULL
3388 **
3389 ** @fcategory new
3390 ******************************************************************************/
3391 
3392 
3393 
3394 
3395 /* @func ensFeatureadaptorNew *************************************************
3396 **
3397 ** Default constructor for an Ensembl Feature Adaptor.
3398 **
3399 ** For Ensembl Collection Core databases storing information about multiple
3400 ** species, only Ensembl Feature objects for a particular species encoded in
3401 ** the Ensembl Database Adaptor need to be selected.
3402 ** This is achieved by automatically adding additional joins to the
3403 ** 'seq_region' and the 'coord_system' table, which contains the
3404 ** 'coord_system.species_id' field to the default SQL condition.
3405 **
3406 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::new
3407 ** @param [u] dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
3408 ** @param [r] Ptablenames [const char* const*] SQL table name array
3409 ** @param [r] Pcolumnnames [const char* const*] SQL column name array
3410 ** @param [rN] leftjoins [const EnsPBaseadaptorLeftjoin]
3411 ** SQL LEFT JOIN condition array
3412 ** @param [rN] defaultcondition [const char*] SQL SELECT default condition
3413 ** @param [rN] finalcondition [const char*] SQL SELECT final condition
3414 ** @param [f] Fstatement [AjBool function] Statement function address
3415 ** @param [fN] Fread [void* function] Read function address
3416 ** @param [fN] Freference [void* function] Reference function address
3417 ** @param [fN] Fwrite [AjBool function] Write function address
3418 ** @param [fN] Fdelete [void function] Delete function address
3419 ** @param [fN] Fsize [size_t function] Size function address
3420 ** @param [f] Fgetfeature [EnsPFeature function] Get Feature function address
3421 ** @param [r] label [const char*] Ensembl Cache label
3422 **
3423 ** @return [EnsPFeatureadaptor] Ensembl Feature Adaptor or NULL
3424 **
3425 ** @release 6.2.0
3426 ** @@
3427 ** NOTE: For Ensembl Feature objects stored in Ensembl Core databases with
3428 ** multiple species, the Sequence Region in a '*_feature' table needs joining
3429 ** to the 'seq_region' table and the 'coord_system' table, which holds the
3430 ** species identifier field.
3431 ** TODO: The Perl API adds the constraint as extra default where clause in the
3432 ** Base Adaptor. This is clearly not the right place as not every Object the
3433 ** Base Adaptor fetches is a Feature. Feature objects are those objects that
3434 ** are associated with a Sequence Region so that the Sequence Region constraint
3435 ** is more natural here.
3436 ** TODO: Suggest to the Ensembl Core team!
3437 ** TODO: Separate this function into an ensFeatureadaptorNew and
3438 ** ensFeatureadaptorNewCache function, since not all Ensembl Feature Adaptors
3439 ** require an Ensembl Cache.
3440 ******************************************************************************/
3441 
ensFeatureadaptorNew(EnsPDatabaseadaptor dba,const char * const * Ptablenames,const char * const * Pcolumnnames,const EnsPBaseadaptorLeftjoin leftjoins,const char * defaultcondition,const char * finalcondition,AjBool (* Fstatement)(EnsPBaseadaptor ba,const AjPStr statement,EnsPAssemblymapper am,EnsPSlice slice,AjPList objects),void * (* Fread)(const void * key),void * (* Freference)(void * value),AjBool (* Fwrite)(const void * value),void (* Fdelete)(void ** Pvalue),size_t (* Fsize)(const void * value),EnsPFeature (* Fgetfeature)(const void * object),const char * label)3442 EnsPFeatureadaptor ensFeatureadaptorNew(
3443     EnsPDatabaseadaptor dba,
3444     const char* const* Ptablenames,
3445     const char* const* Pcolumnnames,
3446     const EnsPBaseadaptorLeftjoin leftjoins,
3447     const char *defaultcondition,
3448     const char *finalcondition,
3449     AjBool (*Fstatement) (EnsPBaseadaptor ba,
3450                           const AjPStr statement,
3451                           EnsPAssemblymapper am,
3452                           EnsPSlice slice,
3453                           AjPList objects),
3454     void* (*Fread) (const void *key),
3455     void* (*Freference) (void *value),
3456     AjBool (*Fwrite) (const void *value),
3457     void (*Fdelete) (void **Pvalue),
3458     size_t (*Fsize) (const void *value),
3459     EnsPFeature (*Fgetfeature) (const void *object),
3460     const char *label)
3461 {
3462     register ajuint i = 0U;
3463 
3464     EnsPFeatureadaptor fa = NULL;
3465 
3466     if (ajDebugTest("ensFeatureadaptorNew"))
3467         ajDebug("ensFeatureadaptorNew\n"
3468                 "  dba %p\n"
3469                 "  Ptablenames %p\n"
3470                 "  Pcolumnnames %p\n"
3471                 "  leftjoins %p\n"
3472                 "  defaultcondition %p\n"
3473                 "  finalcondition %p\n"
3474                 "  Fstatement %p\n"
3475                 "  Fread %p\n"
3476                 "  Freference %p\n"
3477                 "  Fwrite %p\n"
3478                 "  Fdelete %p\n"
3479                 "  Fsize %p\n"
3480                 "  Fgetfeature %p\n"
3481                 "  label '%s'\n",
3482                 dba,
3483                 Ptablenames,
3484                 Pcolumnnames,
3485                 leftjoins,
3486                 defaultcondition,
3487                 finalcondition,
3488                 Fstatement,
3489                 Fread,
3490                 Freference,
3491                 Fwrite,
3492                 Fdelete,
3493                 Fsize,
3494                 Fgetfeature,
3495                 label);
3496 
3497     if (!dba)
3498         return NULL;
3499 
3500     if (!Ptablenames)
3501         return NULL;
3502 
3503     if (!Pcolumnnames)
3504         return NULL;
3505 
3506     if (!Fstatement)
3507         return NULL;
3508 
3509     if (!Fgetfeature)
3510         return NULL;
3511 
3512     AJNEW0(fa);
3513 
3514     if (ensDatabaseadaptorGetMultispecies(dba))
3515     {
3516         /*
3517         ** For Ensembl collection (multi-species) databases, allocate a
3518         ** SQL table name array extended with 'seq_region' and 'coord_system'.
3519         ** This array, instead of the one provided as parameter
3520         ** (const char *const *Ptablenames) will then be passed into the
3521         ** Ensembl Base Adaptor via the ensBaseadaptorNew function.
3522         */
3523 
3524         for (i = 0U; Ptablenames[i]; i++);
3525 
3526         fa->Tablenames = AJCALLOC0(i + 1U + 2U, sizeof (char *));
3527 
3528         for (i = 0U; Ptablenames[i]; i++)
3529             fa->Tablenames[i] = ajCharNewC(Ptablenames[i]);
3530 
3531         fa->Tablenames[i] = ajCharNewC("seq_region");
3532         i++;
3533         fa->Tablenames[i] = ajCharNewC("coord_system");
3534         i++;
3535         fa->Tablenames[i] = NULL;
3536 
3537         Ptablenames = (const char* const *) fa->Tablenames;
3538 
3539         /*
3540         ** Allocate the SQL SELECT default condition and extend for
3541         ** "seq_region" and "coord_system" conditions. This character string,
3542         ** instead of the one provided here (const char *defaultcondition) will
3543         ** then be used by the Ensembl Base Adaptor via ensBaseadaptorNew.
3544         */
3545 
3546         if (defaultcondition)
3547             fa->Defaultcondition = ajFmtString(
3548                 "%s "
3549                 "AND "
3550                 "%s.seq_region_id = seq_region.seq_region_id "
3551                 "AND "
3552                 "seq_region.coord_system_id = coord_system.coord_system_id "
3553                 "AND "
3554                 "coord_system.species_id = %u",
3555                 defaultcondition,
3556                 Ptablenames[0],
3557                 ensDatabaseadaptorGetIdentifier(dba));
3558         else
3559             fa->Defaultcondition = ajFmtString(
3560                 "%s.seq_region_id = "
3561                 "seq_region.seq_region_id "
3562                 "AND "
3563                 "seq_region.coord_system_id = coord_system.coord_system_id "
3564                 "AND "
3565                 "coord_system.species_id = %u",
3566                 Ptablenames[0],
3567                 ensDatabaseadaptorGetIdentifier(dba));
3568 
3569         defaultcondition = (const char *) fa->Defaultcondition;
3570     }
3571 
3572     fa->Adaptor = ensBaseadaptorNew(
3573         dba,
3574         Ptablenames,
3575         Pcolumnnames,
3576         leftjoins,
3577         defaultcondition,
3578         finalcondition,
3579         Fstatement);
3580 
3581     fa->Cache = ensCacheNew(
3582         ensECacheTypeNumeric,
3583         featureadaptorKCacheMaxBytes,
3584         featureadaptorKCacheMaxCount,
3585         featureadaptorKCacheMaxSize,
3586         Freference,
3587         Fdelete,
3588         Fsize,
3589         Fread,
3590         Fwrite,
3591         ajFalse,
3592         label);
3593 
3594     fa->FobjectGetFeature = Fgetfeature;
3595     fa->Freference        = Freference;
3596     fa->Fdelete           = Fdelete;
3597 
3598     fa->Startequalsend = ajFalse;
3599     fa->Maximumlength  = 0;
3600 
3601     return fa;
3602 }
3603 
3604 
3605 
3606 
3607 /* @section destructors *******************************************************
3608 **
3609 ** Destruction destroys all internal data structures and frees the memory
3610 ** allocated for an Ensembl Feature Adaptor object.
3611 **
3612 ** @fdata [EnsPFeatureadaptor]
3613 **
3614 ** @nam3rule Del Destroy (free) an Ensembl Feature Adaptor
3615 **
3616 ** @argrule * Pfa [EnsPFeatureadaptor*] Ensembl Feature Adaptor address
3617 **
3618 ** @valrule * [void]
3619 **
3620 ** @fcategory delete
3621 ******************************************************************************/
3622 
3623 
3624 
3625 
3626 /* @func ensFeatureadaptorDel *************************************************
3627 **
3628 ** Default destructor for an Ensembl Feature Adaptor.
3629 **
3630 ** @param [d] Pfa [EnsPFeatureadaptor*] Ensembl Feature Adaptor address
3631 **
3632 ** @return [void]
3633 **
3634 ** @release 6.2.0
3635 ** @@
3636 ******************************************************************************/
3637 
ensFeatureadaptorDel(EnsPFeatureadaptor * Pfa)3638 void ensFeatureadaptorDel(EnsPFeatureadaptor *Pfa)
3639 {
3640     register ajuint i = 0U;
3641 
3642     EnsPFeatureadaptor pthis = NULL;
3643 
3644     if (!Pfa)
3645         return;
3646 
3647 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
3648     if (ajDebugTest("ensFeatureadaptorDel"))
3649         ajDebug("ensFeatureadaptorDel\n"
3650                 "  *Pfa %p\n",
3651                 *Pfa);
3652 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
3653 
3654     if (!(pthis = *Pfa))
3655         return;
3656 
3657     ensBaseadaptorDel(&pthis->Adaptor);
3658 
3659     ensCacheDel(&pthis->Cache);
3660 
3661     /* Clear the array of SQL table names. */
3662 
3663     if (pthis->Tablenames)
3664     {
3665         for (i = 0U; pthis->Tablenames[i]; i++)
3666             ajCharDel(&pthis->Tablenames[i]);
3667 
3668         AJFREE(pthis->Tablenames);
3669     }
3670 
3671     /* Clear the SQL SELECT default condition. */
3672 
3673     ajCharDel(&pthis->Defaultcondition);
3674 
3675     ajMemFree((void **) Pfa);
3676 
3677     return;
3678 }
3679 
3680 
3681 
3682 
3683 /* @section member retrieval **************************************************
3684 **
3685 ** Functions for returning members of an Ensembl Feature Adaptor object.
3686 **
3687 ** @fdata [EnsPFeatureadaptor]
3688 **
3689 ** @nam3rule Get Return Ensembl Feature Adaptor attribute(s)
3690 ** @nam4rule Baseadaptor      Return the Ensembl Base Adaptor
3691 ** @nam4rule Cache            Return the Ensembl Cache
3692 ** @nam4rule Databaseadaptor  Return the Ensembl Database Adaptor
3693 ** @nam4rule Maximumlength    Return the maximum Feature length
3694 ** @nam4rule Startequalsend   Return the start-equals-end flag
3695 **
3696 ** @argrule * fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3697 **
3698 ** @valrule Baseadaptor [EnsPBaseadaptor] Ensembl Base Adaptor or NULL
3699 ** @valrule Cache [EnsPCache] Ensembl Cache or NULL
3700 ** @valrule Databaseadaptor [EnsPDatabaseadaptor]
3701 ** Ensembl Database Adaptor or NULL
3702 ** @valrule Maximumlength [ajint] Maximum Ensembl Feature length or 0
3703 ** @valrule Startequalsend [AjBool] Start-equals-end flag or ajFalse
3704 **
3705 ** @fcategory use
3706 ******************************************************************************/
3707 
3708 
3709 
3710 
3711 /* @func ensFeatureadaptorGetBaseadaptor **************************************
3712 **
3713 ** Get the Ensembl Base Adaptor member of an Ensembl Feature Adaptor.
3714 **
3715 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3716 **
3717 ** @return [EnsPBaseadaptor] Ensembl Base Adaptor or NULL
3718 **
3719 ** @release 6.2.0
3720 ** @@
3721 ******************************************************************************/
3722 
ensFeatureadaptorGetBaseadaptor(const EnsPFeatureadaptor fa)3723 EnsPBaseadaptor ensFeatureadaptorGetBaseadaptor(
3724     const EnsPFeatureadaptor fa)
3725 {
3726     return (fa) ? fa->Adaptor : NULL;
3727 }
3728 
3729 
3730 
3731 
3732 /* @func ensFeatureadaptorGetCache ********************************************
3733 **
3734 ** Get the Ensembl Cache member of an Ensembl Feature Adaptor.
3735 **
3736 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3737 **
3738 ** @return [EnsPCache] Ensembl Cache or NULL
3739 **
3740 ** @release 6.2.0
3741 ** @@
3742 ******************************************************************************/
3743 
ensFeatureadaptorGetCache(const EnsPFeatureadaptor fa)3744 EnsPCache ensFeatureadaptorGetCache(
3745     const EnsPFeatureadaptor fa)
3746 {
3747     return (fa) ? fa->Cache : NULL;
3748 }
3749 
3750 
3751 
3752 
3753 /* @func ensFeatureadaptorGetDatabaseadaptor **********************************
3754 **
3755 ** Get the Ensembl Database Adaptor member of the
3756 ** Ensembl Base Adaptor member of an Ensembl Feature Adaptor.
3757 **
3758 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3759 **
3760 ** @return [EnsPDatabaseadaptor] Ensembl Database Adaptor or NULL
3761 **
3762 ** @release 6.2.0
3763 ** @@
3764 ******************************************************************************/
3765 
ensFeatureadaptorGetDatabaseadaptor(const EnsPFeatureadaptor fa)3766 EnsPDatabaseadaptor ensFeatureadaptorGetDatabaseadaptor(
3767     const EnsPFeatureadaptor fa)
3768 {
3769     return ensBaseadaptorGetDatabaseadaptor(
3770         ensFeatureadaptorGetBaseadaptor(fa));
3771 }
3772 
3773 
3774 
3775 
3776 /* @func ensFeatureadaptorGetMaximumlength ************************************
3777 **
3778 ** Get the maximum length member of an Ensembl Feature Adaptor.
3779 **
3780 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3781 **
3782 ** @return [ajint] Maximum length or 0
3783 **
3784 ** @release 6.4.0
3785 ** @@
3786 ******************************************************************************/
3787 
ensFeatureadaptorGetMaximumlength(const EnsPFeatureadaptor fa)3788 ajint ensFeatureadaptorGetMaximumlength(
3789     const EnsPFeatureadaptor fa)
3790 {
3791     return (fa) ? fa->Maximumlength : 0;
3792 }
3793 
3794 
3795 
3796 
3797 /* @func ensFeatureadaptorGetStartequalsend ***********************************
3798 **
3799 ** Get the start-equals-end flag member of an Ensembl Feature Adaptor.
3800 **
3801 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
3802 **
3803 ** @return [AjBool] Start-equals-end flag or ajFalse
3804 **
3805 ** @release 6.5.0
3806 ** @@
3807 ******************************************************************************/
3808 
ensFeatureadaptorGetStartequalsend(const EnsPFeatureadaptor fa)3809 AjBool ensFeatureadaptorGetStartequalsend(
3810     const EnsPFeatureadaptor fa)
3811 {
3812     return (fa) ? fa->Startequalsend : ajFalse;
3813 }
3814 
3815 
3816 
3817 
3818 /* @section member assignment *************************************************
3819 **
3820 ** Functions for assigning members of an Ensembl Feature Adaptor object.
3821 **
3822 ** @fdata [EnsPFeatureadaptor]
3823 **
3824 ** @nam3rule Set Set one member of an Ensembl Feature Adaptor
3825 ** @nam4rule Columnnames Set the SQL column name array
3826 ** @nam4rule Defaultcondition Set the SQL SELECT default condition
3827 ** @nam4rule Finalcondition Set the SQL SELECT final condition
3828 ** @nam4rule Maximumlength Set the maximum Feature length
3829 ** @nam4rule Startequalsend Set the start-equals-end flag
3830 ** @nam4rule Tablenames Set the SQL table name array
3831 **
3832 ** @argrule * fa [EnsPFeatureadaptor] Ensembl Feature Adaptor object
3833 ** @argrule Columnnames Pcolumnnames [const char* const*]
3834 ** SQL column name array
3835 ** @argrule Defaultcondition defaultcondition [const char*]
3836 ** SQL SELECT default condition
3837 ** @argrule Finalcondition finalcondition [const char*]
3838 ** SQL SELECT final condition
3839 ** @argrule Maximumlength length [ajint] Maximum length
3840 ** @argrule Startequalsend flag [AjBool] Start-equals-end flag
3841 ** @argrule Tablenames Ptablenames [const char* const*] SQL table name array
3842 **
3843 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
3844 **
3845 ** @fcategory modify
3846 ******************************************************************************/
3847 
3848 
3849 
3850 
3851 /* @func ensFeatureadaptorSetColumnnames **************************************
3852 **
3853 ** Set the SQL column name array member of the
3854 ** Ensembl Base Adaptor member of an
3855 ** Ensembl Feature Adaptor.
3856 **
3857 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
3858 ** @param [r] Pcolumnnames [const char* const*] SQL column name array
3859 **
3860 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3861 **
3862 ** @release 6.2.0
3863 ** @@
3864 ******************************************************************************/
3865 
ensFeatureadaptorSetColumnnames(EnsPFeatureadaptor fa,const char * const * Pcolumnnames)3866 AjBool ensFeatureadaptorSetColumnnames(EnsPFeatureadaptor fa,
3867                                        const char* const* Pcolumnnames)
3868 {
3869     return ensBaseadaptorSetColumnnames(
3870         ensFeatureadaptorGetBaseadaptor(fa),
3871         Pcolumnnames);
3872 }
3873 
3874 
3875 
3876 
3877 /* @func ensFeatureadaptorSetDefaultcondition *********************************
3878 **
3879 ** Set the SQL SELECT default condition member of the
3880 ** Ensembl Base Adaptor member of an Ensembl Feature Adaptor.
3881 **
3882 ** For Ensembl Collection Core databases storing information about multiple
3883 ** species, only Ensembl Feature objects for a particular species encoded in
3884 ** the Ensembl Database Adaptor need to be selected.
3885 ** This is achieved by automatically adding additional joins to the
3886 ** 'seq_region' and the 'coord_system' table, which contains the
3887 ** 'coord_system.species_id' field to the SQL SELECT default condition.
3888 **
3889 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
3890 ** @param [rN] defaultcondition [const char*] SQL SELECT default condition
3891 **
3892 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3893 **
3894 ** @release 6.4.0
3895 ** @@
3896 ******************************************************************************/
3897 
ensFeatureadaptorSetDefaultcondition(EnsPFeatureadaptor fa,const char * defaultcondition)3898 AjBool ensFeatureadaptorSetDefaultcondition(EnsPFeatureadaptor fa,
3899                                             const char *defaultcondition)
3900 {
3901     EnsPDatabaseadaptor dba = NULL;
3902 
3903     if (!fa)
3904         return ajFalse;
3905 
3906     dba = ensFeatureadaptorGetDatabaseadaptor(fa);
3907 
3908     if (!dba)
3909         return ajFalse;
3910 
3911     if (ensDatabaseadaptorGetMultispecies(dba))
3912     {
3913         /* Clear the SQL SELECT default condition. */
3914 
3915         ajCharDel(&fa->Defaultcondition);
3916 
3917         /*
3918         ** Allocate the SQL SELECT default condition and extend for
3919         ** "seq_region" and "coord_system" conditions. This character string,
3920         ** instead of the one provided here (const char *defaultcondition) will
3921         ** then be set in the Ensembl Base Adaptor via
3922         ** ensBaseadaptorSetDefaultcondition.
3923         */
3924 
3925         if (defaultcondition)
3926             fa->Defaultcondition = ajFmtString(
3927                 "%s "
3928                 "AND "
3929                 "%s.seq_region_id = seq_region.seq_region_id "
3930                 "AND "
3931                 "seq_region.coord_system_id = coord_system.coord_system_id "
3932                 "AND "
3933                 "coord_system.species_id = %u",
3934                 defaultcondition,
3935                 ensBaseadaptorGetPrimarytable(
3936                     ensFeatureadaptorGetBaseadaptor(fa)),
3937                 ensDatabaseadaptorGetIdentifier(dba));
3938         else
3939             fa->Defaultcondition = ajFmtString(
3940                 "%s.seq_region_id = seq_region.seq_region_id "
3941                 "AND "
3942                 "seq_region.coord_system_id = coord_system.coord_system_id "
3943                 "AND "
3944                 "coord_system.species_id = %u",
3945                 ensBaseadaptorGetPrimarytable(
3946                     ensFeatureadaptorGetBaseadaptor(fa)),
3947                 ensDatabaseadaptorGetIdentifier(dba));
3948 
3949         defaultcondition = (const char *) fa->Defaultcondition;
3950     }
3951 
3952     return ensBaseadaptorSetDefaultcondition(
3953         ensFeatureadaptorGetBaseadaptor(fa),
3954         defaultcondition);
3955 }
3956 
3957 
3958 
3959 
3960 /* @func ensFeatureadaptorSetFinalcondition ***********************************
3961 **
3962 ** Set the SQL SELECT final condition member of the
3963 ** Ensembl Base Adaptor member of an Ensembl Base Adaptor.
3964 **
3965 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
3966 ** @param [r] finalcondition [const char*] SQL SELECT final condition
3967 **
3968 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3969 **
3970 ** @release 6.4.0
3971 ** @@
3972 ******************************************************************************/
3973 
ensFeatureadaptorSetFinalcondition(EnsPFeatureadaptor fa,const char * finalcondition)3974 AjBool ensFeatureadaptorSetFinalcondition(EnsPFeatureadaptor fa,
3975                                           const char *finalcondition)
3976 {
3977     if (!fa)
3978         return ajFalse;
3979 
3980     return ensBaseadaptorSetFinalcondition(
3981         ensFeatureadaptorGetBaseadaptor(fa),
3982         finalcondition);
3983 }
3984 
3985 
3986 
3987 
3988 /* @func ensFeatureadaptorSetMaximumlength ************************************
3989 **
3990 ** Set the maximum length member of an Ensembl Feature Adaptor.
3991 **
3992 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
3993 ** @param [r] length [ajint] Maximum length
3994 **
3995 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3996 **
3997 ** @release 6.4.0
3998 ** @@
3999 ******************************************************************************/
4000 
ensFeatureadaptorSetMaximumlength(EnsPFeatureadaptor fa,ajint length)4001 AjBool ensFeatureadaptorSetMaximumlength(EnsPFeatureadaptor fa,
4002                                          ajint length)
4003 {
4004     if (!fa)
4005         return ajFalse;
4006 
4007     fa->Maximumlength = length;
4008 
4009     return ajTrue;
4010 }
4011 
4012 
4013 
4014 
4015 /* @func ensFeatureadaptorSetStartequalsend ***********************************
4016 **
4017 ** Set the start-equals-end flag member of an Ensembl Feature Adaptor.
4018 **
4019 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4020 ** @param [r] flag [AjBool] Start-equals-end flag
4021 **
4022 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4023 **
4024 ** @release 6.5.0
4025 ** @@
4026 ******************************************************************************/
4027 
ensFeatureadaptorSetStartequalsend(EnsPFeatureadaptor fa,AjBool flag)4028 AjBool ensFeatureadaptorSetStartequalsend(EnsPFeatureadaptor fa,
4029                                           AjBool flag)
4030 {
4031     if (!fa)
4032         return ajFalse;
4033 
4034     fa->Startequalsend = flag;
4035 
4036     return ajTrue;
4037 }
4038 
4039 
4040 
4041 
4042 /* @func ensFeatureadaptorSetTablenames ***************************************
4043 **
4044 ** Set the SQL table name array member of the
4045 ** Ensembl Base Adaptor member of an
4046 ** Ensembl Feature Adaptor.
4047 **
4048 ** For Ensembl Collection Core databases storing information about multiple
4049 ** species, only Ensembl Feature objects for a particular species encoded in
4050 ** the Ensembl Database Adaptor need to be selected.
4051 ** This is achieved by automatically adding additional joins to the
4052 ** "seq_region" and the "coord_system" table, which contains the
4053 ** "coord_system.species_id" field to the SQL SELECT default condition.
4054 **
4055 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4056 ** @param [r] Ptablenames [const char* const*] SQL table name array
4057 **
4058 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4059 **
4060 ** @release 6.2.0
4061 ** @@
4062 ******************************************************************************/
4063 
ensFeatureadaptorSetTablenames(EnsPFeatureadaptor fa,const char * const * Ptablenames)4064 AjBool ensFeatureadaptorSetTablenames(EnsPFeatureadaptor fa,
4065                                       const char* const* Ptablenames)
4066 {
4067     register ajuint i = 0U;
4068 
4069     EnsPDatabaseadaptor dba = NULL;
4070 
4071     if (!fa)
4072         return ajFalse;
4073 
4074     if (!Ptablenames)
4075         return ajFalse;
4076 
4077     dba = ensFeatureadaptorGetDatabaseadaptor(fa);
4078 
4079     if (!dba)
4080         return ajFalse;
4081 
4082     if (ensDatabaseadaptorGetMultispecies(dba))
4083     {
4084         /* Clear the array of table names. */
4085 
4086         if (fa->Tablenames)
4087         {
4088             for (i = 0U; fa->Tablenames[i]; i++)
4089                 ajCharDel(&fa->Tablenames[i]);
4090 
4091             AJFREE(fa->Tablenames);
4092         }
4093 
4094         /*
4095         ** Allocate an SQL table name array extended for 'seq_region' and
4096         ** 'coord_system' table names. This array, instead of the one provided
4097         ** here (const char *const *Ptablenames) will then be set in the
4098         ** Ensembl Base Adaptor via ensBaseadaptorSetTablenames.
4099         */
4100 
4101         for (i = 0U; Ptablenames[i]; i++);
4102 
4103         fa->Tablenames = AJCALLOC0(i + 1U + 2U, sizeof (char *));
4104 
4105         for (i = 0U; Ptablenames[i]; i++)
4106             fa->Tablenames[i] = ajCharNewC(Ptablenames[i]);
4107 
4108         fa->Tablenames[i] = ajCharNewC("seq_region");
4109         i++;
4110         fa->Tablenames[i] = ajCharNewC("coord_system");
4111         i++;
4112         fa->Tablenames[i] = NULL;
4113 
4114         Ptablenames = (const char* const *) fa->Tablenames;
4115     }
4116 
4117     return ensBaseadaptorSetTablenames(
4118         ensFeatureadaptorGetBaseadaptor(fa),
4119         Ptablenames);
4120 }
4121 
4122 
4123 
4124 
4125 /* @section SQL character escaping ********************************************
4126 **
4127 ** Ensembl Feature Adaptor SQL character escaping convenience functions
4128 **
4129 ** @fdata [EnsPFeatureadaptor]
4130 **
4131 ** @nam3rule Escape Escape strings
4132 ** @nam4rule C Escape an AJAX String
4133 ** @nam4rule S Escape a C-type character string
4134 **
4135 ** @argrule * fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4136 ** @argrule EscapeC Ptxt [char**] Address of the (new) SQL-escaped C string
4137 ** @argrule EscapeC str [const AjPStr] AJAX String to be escaped
4138 ** @argrule EscapeS Pstr [AjPStr*] Address of the (new) SQL-escaped AJAX String
4139 ** @argrule EscapeS str [const AjPStr] AJAX String to be escaped
4140 **
4141 ** @valrule EscapeC [AjBool] ajTrue upon success, ajFalse otherwise
4142 ** @valrule EscapeS [AjBool] ajTrue upon success, ajFalse otherwise
4143 **
4144 ** @fcategory use
4145 ******************************************************************************/
4146 
4147 
4148 
4149 
4150 /* @func ensFeatureadaptorEscapeC *********************************************
4151 **
4152 ** Escape special characters in an AJAX String for use in an SQL statement,
4153 ** taking into account the current character set of the AJAX SQL Connection
4154 ** and return a C-type character string.
4155 **
4156 ** The caller is responsible for deleting the escaped C-type character string.
4157 **
4158 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4159 ** @param [wP] Ptxt [char**] Address of the (new) SQL-escaped C string
4160 ** @param [r] str [const AjPStr] AJAX String to be escaped
4161 **
4162 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4163 **
4164 ** @release 6.2.0
4165 ** @@
4166 ******************************************************************************/
4167 
ensFeatureadaptorEscapeC(EnsPFeatureadaptor fa,char ** Ptxt,const AjPStr str)4168 AjBool ensFeatureadaptorEscapeC(EnsPFeatureadaptor fa,
4169                                 char **Ptxt,
4170                                 const AjPStr str)
4171 {
4172 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
4173     if (ajDebugTest("ensFeatureadaptorEscapeC"))
4174         ajDebug("ensFeatureadaptorEscapeC\n"
4175                 "  fa %p\n"
4176                 "  Ptxt %p\n"
4177                 "  str '%S'\n",
4178                 fa,
4179                 Ptxt,
4180                 str);
4181 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
4182 
4183     return ensBaseadaptorEscapeC(
4184         ensFeatureadaptorGetBaseadaptor(fa),
4185         Ptxt,
4186         str);
4187 }
4188 
4189 
4190 
4191 
4192 /* @func ensFeatureadaptorEscapeS *********************************************
4193 **
4194 ** Escape special characters in an AJAX String for use in an SQL statement,
4195 ** taking into account the current character set of the AJAX SQL Connection
4196 ** and return an AJAX String.
4197 **
4198 ** The caller is responsible for deleting the escaped AJAX String.
4199 **
4200 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4201 ** @param [wP] Pstr [AjPStr*] Address of the (new) SQL-escaped AJAX String
4202 ** @param [r] str [const AjPStr] AJAX String to be escaped
4203 **
4204 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4205 **
4206 ** @release 6.2.0
4207 ** @@
4208 ******************************************************************************/
4209 
ensFeatureadaptorEscapeS(EnsPFeatureadaptor fa,AjPStr * Pstr,const AjPStr str)4210 AjBool ensFeatureadaptorEscapeS(EnsPFeatureadaptor fa,
4211                                 AjPStr *Pstr,
4212                                 const AjPStr str)
4213 {
4214 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
4215     if (ajDebugTest("ensFeatureadaptorEscapeS"))
4216         ajDebug("ensFeatureadaptorEscapeS\n"
4217                 "  fa %p\n"
4218                 "  Pstr %p\n"
4219                 "  str '%S'\n",
4220                 fa,
4221                 Pstr,
4222                 str);
4223 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
4224 
4225     return ensBaseadaptorEscapeS(
4226         ensFeatureadaptorGetBaseadaptor(fa),
4227         Pstr,
4228         str);
4229 }
4230 
4231 
4232 
4233 
4234 /* @section SQL statement constraint ******************************************
4235 **
4236 ** Ensembl Feature Adaptor SQL statement constraint functions
4237 **
4238 ** @fdata [EnsPFeatureadaptor]
4239 **
4240 ** @nam3rule Constraint Manipulate SQL statement constraints
4241 ** @nam4rule Append Append a condition to an SQL statement constraint
4242 ** @nam5rule Analysisname Ensembl Analysis name
4243 **
4244 ** @argrule * fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
4245 ** @argrule Constraint Pconstraint [AjPStr*] SQL constraint address
4246 ** @argrule Analysisname anname [const AjPStr] Ensembl Analysis name
4247 **
4248 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
4249 **
4250 ** @fcategory use
4251 ******************************************************************************/
4252 
4253 
4254 
4255 
4256 /* @func ensFeatureadaptorConstraintAppendAnalysisname ************************
4257 **
4258 ** Append an Ensembl Analysis condition to an SQL statement constraint via an
4259 ** Ensembl Analysis name.
4260 **
4261 ** The caller is responsible for deleting the SQL statement constraint.
4262 **
4263 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::_logic_name_to_constraint
4264 ** @param [r] fa [const EnsPFeatureadaptor] Ensembl Feature Adaptor
4265 ** @param [uN] Pconstraint [AjPStr*] SQL statement constraint address
4266 ** @param [rN] anname [const AjPStr] Ensembl Analysis name
4267 **
4268 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4269 **
4270 ** @release 6.4.0
4271 ** @@
4272 ** Given an Ensembl Analysis name and an existing constraint this will
4273 ** add an 'analysis' table constraint to the Feature. Note that if no
4274 ** 'analysis_id' exists in the columns of the primary table then no
4275 ** constraint is added at all.
4276 ******************************************************************************/
4277 
ensFeatureadaptorConstraintAppendAnalysisname(const EnsPFeatureadaptor fa,AjPStr * Pconstraint,const AjPStr anname)4278 AjBool ensFeatureadaptorConstraintAppendAnalysisname(
4279     const EnsPFeatureadaptor fa,
4280     AjPStr *Pconstraint,
4281     const AjPStr anname)
4282 {
4283     const char *const *columns = NULL;
4284     const char        *table   = NULL;
4285 
4286     register ajuint i = 0U;
4287 
4288     AjBool match = AJFALSE;
4289 
4290     EnsPAnalysis analysis  = NULL;
4291     EnsPAnalysisadaptor aa = NULL;
4292 
4293     EnsPDatabaseadaptor dba = NULL;
4294 
4295     if (!fa)
4296         return ajFalse;
4297 
4298     if (!Pconstraint)
4299         return ajFalse;
4300 
4301     if (!anname)
4302         return ajTrue;
4303 
4304     if (ajDebugTest("ensFeatureadaptorConstraintAppendAnalysisname"))
4305         ajDebug("ensFeatureadaptorConstraintAppendAnalysisname\n"
4306                 "  fa %p\n"
4307                 "  *Pconstraint '%S'\n"
4308                 "  anname '%S'\n",
4309                 fa,
4310                 *Pconstraint,
4311                 anname);
4312 
4313     /*
4314     ** Check that the primary table, which is the first one in the list of
4315     ** tables, actually contains an 'analysis_id' column.
4316     */
4317 
4318     columns = ensBaseadaptorGetColumnnames(
4319         ensFeatureadaptorGetBaseadaptor(fa));
4320 
4321     table = ensBaseadaptorGetPrimarytable(
4322         ensFeatureadaptorGetBaseadaptor(fa));
4323 
4324     while (columns[i])
4325     {
4326         if (ajCharPrefixC(columns[i], table) &&
4327             ajCharSuffixC(columns[i], ".analysis_id"))
4328             match = ajTrue;
4329 
4330         i++;
4331     }
4332 
4333     if (!match)
4334     {
4335         ajWarn("ensFeatureadaptorConstraintAppendAnalysisname called for an "
4336                "Ensembl Feature, which is not associated with an "
4337                "Ensembl Analysis. Ignoring Analysis name argument '%S'.\n",
4338                anname);
4339 
4340         return ajFalse;
4341     }
4342 
4343     dba = ensFeatureadaptorGetDatabaseadaptor(fa);
4344 
4345     aa = ensRegistryGetAnalysisadaptor(dba);
4346 
4347     ensAnalysisadaptorFetchByName(aa, anname, &analysis);
4348 
4349     if (!analysis)
4350         return ajFalse;
4351 
4352     if (*Pconstraint && ajStrGetLen(*Pconstraint))
4353         ajStrAppendC(Pconstraint, " AND ");
4354     else
4355         *Pconstraint = ajStrNew();
4356 
4357     ajFmtPrintAppS(Pconstraint,
4358                    "%s.analysis_id = %u",
4359                    table,
4360                    ensAnalysisGetIdentifier(analysis));
4361 
4362     ensAnalysisDel(&analysis);
4363 
4364     return ajTrue;
4365 }
4366 
4367 
4368 
4369 
4370 /* @funcstatic featureadaptorRemap ********************************************
4371 **
4372 ** Remap Ensembl Objects based on Ensembl Feature objects onto an
4373 ** Ensembl Slice.
4374 **
4375 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::_remap
4376 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4377 ** @param [u] objects [AjPList] AJAX List of Ensembl Objects based on
4378 **                              Ensembl Feature objects
4379 ** @param [uN] am [EnsPAssemblymapper] Ensembl Assembly Mapper
4380 ** @param [u] slice [EnsPSlice] Ensembl Slice
4381 **
4382 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4383 **
4384 ** @release 6.3.0
4385 ** @@
4386 ******************************************************************************/
4387 
featureadaptorRemap(EnsPFeatureadaptor fa,AjPList objects,EnsPAssemblymapper am,EnsPSlice slice)4388 static AjBool featureadaptorRemap(EnsPFeatureadaptor fa,
4389                                   AjPList objects,
4390                                   EnsPAssemblymapper am,
4391                                   EnsPSlice slice)
4392 {
4393     ajint start  = 0;
4394     ajint end    = 0;
4395     ajint strand = 0;
4396 
4397     ajuint srid = 0U;
4398 
4399     void *Pobject = NULL;
4400 
4401     AjBool debug = AJFALSE;
4402 
4403     AjIList iter = NULL;
4404     AjPList mrs  = NULL;
4405 
4406     EnsPFeature feature = NULL;
4407 
4408     EnsPMapperresult mr = NULL;
4409 
4410     debug = ajDebugTest("featureadaptorRemap");
4411 
4412     if (debug)
4413         ajDebug("featureadaptorRemap\n"
4414                 "  fa %p\n"
4415                 "  objects %p\n"
4416                 "  am %p\n"
4417                 "  slice %p\n",
4418                 fa,
4419                 objects,
4420                 am,
4421                 slice);
4422 
4423     if (!fa)
4424         return ajFalse;
4425 
4426     if (!objects)
4427         return ajFalse;
4428 
4429     if (!slice)
4430         return ajFalse;
4431 
4432     /*
4433     ** Remapping is not required, if the AJAX List is empty or the Slice
4434     ** attached to the first Feature is already identical to the Slice
4435     ** the Feature objects should be mapped to.
4436     */
4437 
4438     if (!ajListGetLength(objects))
4439         return ajTrue;
4440 
4441     ajListPeekFirst(objects, (void **) &Pobject);
4442 
4443     feature = (*fa->FobjectGetFeature) (Pobject);
4444 
4445     if (ensSliceMatch(ensFeatureGetSlice(feature), slice))
4446         return ajTrue;
4447 
4448     /* Remapping has not been done, we have to do our own conversion. */
4449 
4450     mrs = ajListNew();
4451 
4452     iter = ajListIterNew(objects);
4453 
4454     while (!ajListIterDone(iter))
4455     {
4456         Pobject = ajListIterGet(iter);
4457 
4458         feature = (*fa->FobjectGetFeature) (Pobject);
4459 
4460         /*
4461         ** Since Ensembl Feature objects were obtained in contig coordinates,
4462         ** the attached Sequence Region is a contig.
4463         */
4464 
4465         if (!feature->Slice)
4466             ajFatal("featureadaptorRemap got an Ensembl Feature (%p) "
4467                     "without an Ensembl Slice.\n", feature);
4468 
4469         if (ensCoordsystemMatch(ensSliceGetCoordsystemObject(slice),
4470                                 ensSliceGetCoordsystemObject(feature->Slice)))
4471         {
4472             /*
4473             ** The Slice attached to the Feature is in the same
4474             ** Coordinate System as the target Slice, therefore remapping and
4475             ** an Ensembl Assembly Mapper are not required. Nevertheless,
4476             ** coordinates need still adjusting to the Slice.
4477             */
4478 
4479             srid   = ensSliceGetSeqregionIdentifier(feature->Slice);
4480             start  = feature->Start;
4481             end    = feature->End;
4482             strand = feature->Strand;
4483         }
4484         else
4485         {
4486             /*
4487             ** The Slice attached to the Feature is in a different
4488             ** Coordinate System, therefore remapping is required.
4489             */
4490 
4491             if (!am)
4492                 ajFatal("featureadaptorRemap requires an "
4493                         "Ensembl Assembly Mapper, when "
4494                         "Ensembl Coordinate System objects of "
4495                         "Ensembl Feature objects and "
4496                         "Ensembl Slice differ.\n");
4497 
4498             ensAssemblymapperMapSeqregion(am,
4499                                           ensSliceGetSeqregion(feature->Slice),
4500                                           feature->Start,
4501                                           feature->End,
4502                                           feature->Strand,
4503                                           ajTrue,
4504                                           mrs);
4505 
4506             /*
4507             ** The ensAssemblymapperMapSeqregion function in fastmap mode
4508             ** returns at maximum one Ensembl Mapper Result.
4509             ** An empty AJAX List of Ensembl Mapper Result objects
4510             ** means a gap, so remove the Ensembl Object from the AJAX List
4511             ** of Ensembl Objects and delete it.
4512             */
4513 
4514             if (ajListGetLength(mrs))
4515             {
4516                 ajListPeekFirst(mrs, (void **) &mr);
4517 
4518                 srid   = ensMapperresultGetObjectidentifier(mr);
4519                 start  = ensMapperresultGetCoordinateStart(mr);
4520                 end    = ensMapperresultGetCoordinateEnd(mr);
4521                 strand = ensMapperresultGetCoordinateStrand(mr);
4522 
4523                 while (ajListPop(mrs, (void **) &mr))
4524                     ensMapperresultDel(&mr);
4525             }
4526             else
4527             {
4528                 if (debug)
4529                 {
4530                     ajDebug("featureadaptorRemap deleted Ensembl Object (%p), "
4531                             "which associated Ensembl Feature (%p) maps into "
4532                             "a gap.\n", Pobject, feature);
4533 
4534                     ensFeatureTrace(feature, 1);
4535                 }
4536 
4537                 ajListIterRemove(iter);
4538 
4539                 (*fa->Fdelete) (&Pobject);
4540 
4541                 continue;
4542             }
4543         }
4544 
4545         /*
4546         ** If the Ensembl Feature maps to a region outside the desired area,
4547         ** remove the Ensembl Object from the AJAX List of Ensembl Objects
4548         ** and delete it.
4549         */
4550 
4551         if ((srid != ensSliceGetSeqregionIdentifier(slice)) ||
4552             (start > ensSliceGetEnd(slice)) ||
4553             (end   < ensSliceGetStart(slice)))
4554         {
4555             if (debug)
4556             {
4557                 ajDebug("featureadaptorRemap deleted Ensembl Object (%p), "
4558                         "which associated Ensembl Feature (%p:%u:%d:%d:%d) "
4559                         "maps outside the requested region %u:%d:%d:%d.\n",
4560                         Pobject, feature, srid, start, end, strand,
4561                         ensSliceGetSeqregionIdentifier(slice),
4562                         ensSliceGetStart(slice),
4563                         ensSliceGetEnd(slice),
4564                         ensSliceGetStrand(slice));
4565 
4566                 ensFeatureTrace(feature, 1);
4567             }
4568 
4569             ajListIterRemove(iter);
4570 
4571             (*fa->Fdelete) (&Pobject);
4572 
4573             continue;
4574         }
4575 
4576         /* Shift the Feature start, end and strand in one call. */
4577 
4578         if (ensSliceGetStrand(slice) > 0)
4579             ensFeatureMove(feature,
4580                            start - ensSliceGetStart(slice) + 1,
4581                            end   - ensSliceGetStart(slice) + 1,
4582                            +strand);
4583         else
4584             ensFeatureMove(feature,
4585                            ensSliceGetEnd(slice) - end   + 1,
4586                            ensSliceGetEnd(slice) - start + 1,
4587                            -strand);
4588 
4589         ensFeatureSetSlice(feature, slice);
4590     }
4591 
4592     ajListIterDel(&iter);
4593 
4594     ajListFree(&mrs);
4595 
4596     return ajTrue;
4597 }
4598 
4599 
4600 
4601 
4602 /* @funcstatic featureadaptorSliceFetch ***************************************
4603 **
4604 ** Helper function used by ensFeatureadaptorFetchAllbySlice.
4605 **
4606 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::_slice_fetch
4607 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
4608 ** @param [u] slice [EnsPSlice] Ensembl Slice
4609 ** @param [u] constraint [AjPStr] SQL statement constraint
4610 ** @param [u] objects [AjPList] AJAX List of Ensembl Objects
4611 **
4612 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4613 **
4614 ** @release 6.3.0
4615 ** @@
4616 ******************************************************************************/
4617 
featureadaptorSliceFetch(EnsPFeatureadaptor fa,EnsPSlice slice,AjPStr constraint,AjPList objects)4618 static AjBool featureadaptorSliceFetch(EnsPFeatureadaptor fa,
4619                                        EnsPSlice slice,
4620                                        AjPStr constraint,
4621                                        AjPList objects)
4622 {
4623     const char *table = NULL;
4624 
4625     ajuint extsrid   = 0U;
4626     ajuint intsrid   = 0U;
4627     ajuint mrslength = 0U;
4628 
4629     AjBool circular = AJFALSE;
4630     AjBool toplevel = AJFALSE;
4631 
4632     AjIList iter = NULL;
4633 
4634     AjPList css = NULL; /* Ensembl Coordinate System objects */
4635     AjPList mis = NULL; /* Ensembl Meta-Information objects */
4636     AjPList mrs = NULL; /* Ensembl Mapper Result objects */
4637     AjPList pos = NULL; /* Primary Objects */
4638 
4639     AjPStr key       = NULL;
4640     AjPStr tmpconstr = NULL;
4641     AjPStr srids     = NULL;
4642 
4643     EnsPAssemblymapper am         = NULL;
4644     EnsPAssemblymapperadaptor ama = NULL;
4645 
4646     EnsPBaseadaptor ba = NULL;
4647 
4648     EnsPCoordsystem cs         = NULL;
4649     EnsPCoordsystemadaptor csa = NULL;
4650 
4651     EnsPDatabaseadaptor dba = NULL;
4652 
4653     EnsPMapperresult mr = NULL;
4654 
4655     EnsPMetainformation mi         = NULL;
4656     EnsPMetainformationadaptor mia = NULL;
4657 
4658     EnsPMetacoordinateadaptor mca = NULL;
4659 
4660     if (ajDebugTest("featureadaptorSliceFetch"))
4661         ajDebug("featureadaptorSliceFetch\n"
4662                 "  fa %p\n"
4663                 "  slice %p\n"
4664                 "  constraint '%S'\n"
4665                 "  objects %p\n",
4666                 fa,
4667                 slice,
4668                 constraint,
4669                 objects);
4670 
4671     if (!fa)
4672         return ajFalse;
4673 
4674     if (!slice)
4675         return ajFalse;
4676 
4677     if (!constraint)
4678         return ajFalse;
4679 
4680     if (!objects)
4681         return ajFalse;
4682 
4683     ba = ensFeatureadaptorGetBaseadaptor(fa);
4684 
4685     dba = ensBaseadaptorGetDatabaseadaptor(ba);
4686 
4687     if (!dba)
4688     {
4689         ajDebug("featureadaptorSliceFetch got Ensembl Feature Adaptor "
4690                 "without an Ensembl Database Adaptor.\n");
4691 
4692         return ajFalse;
4693     }
4694 
4695     if (!ensSliceIsCircular(slice, &circular))
4696     {
4697         ajDebug("featureadaptorSliceFetch could not call ensSliceIsCircular "
4698                 "successfully.\n");
4699 
4700         ensSliceTrace(slice, 1);
4701 
4702         return ajFalse;
4703     }
4704 
4705     if (!ensSliceIsToplevel(slice, &toplevel))
4706     {
4707         ajDebug("featureadaptorSliceFetch could not call ensSliceIsToplevel "
4708                 "successfully.\n");
4709 
4710         ensSliceTrace(slice, 1);
4711 
4712         return ajFalse;
4713     }
4714 
4715     ama = ensRegistryGetAssemblymapperadaptor(dba);
4716     csa = ensRegistryGetCoordsystemadaptor(dba);
4717     mia = ensRegistryGetMetainformationadaptor(dba);
4718     mca = ensRegistryGetMetacoordinateadaptor(dba);
4719 
4720     /*
4721     ** Fetch the *build.level Ensembl Meta-Information entry, which specifies
4722     ** in which Coordinate System this particular Feature has been annotated.
4723     */
4724 
4725     table = ensBaseadaptorGetPrimarytable(ba);
4726 
4727     key = ajFmtStr("%sbuild.level", table);
4728 
4729     mis = ajListNew();
4730 
4731     ensMetainformationadaptorFetchAllbyKey(mia, key, mis);
4732 
4733     ajStrAssignC(&key, table);
4734 
4735     css = ajListNew();
4736 
4737     if (ajListGetLength(mis) && toplevel)
4738         ajListPushAppend(
4739             css,
4740             (void *) ensCoordsystemNewRef(
4741                 ensSliceGetCoordsystemObject(slice)));
4742     else
4743         ensMetacoordinateadaptorRetrieveAllCoordsystems(mca, key, css);
4744 
4745     while (ajListPop(mis, (void **) &mi))
4746         ensMetainformationDel(&mi);
4747 
4748     ajListFree(&mis);
4749 
4750     ajStrDel(&key);
4751 
4752     /*
4753     ** Fetch the Feature objects for each Coordinate System they are stored in.
4754     ** This may require projecting the Slice for which the Feature objects
4755     ** have been requested into the Coordinate System they have been
4756     ** annotated in.
4757     */
4758 
4759     while (ajListPop(css, (void **) &cs))
4760     {
4761         if (ensCoordsystemMatch(cs, ensSliceGetCoordsystemObject(slice)))
4762         {
4763             /*
4764             ** No mapping is required as the Ensembl Coordinate System objects
4765             ** of Ensembl Feature and Ensembl Slice are identical.
4766             */
4767 
4768             if (!fa->Maximumlength)
4769             {
4770                 key = ajStrNewC(table);
4771 
4772                 ensMetacoordinateadaptorRetrieveMaximumlength(
4773                     mca,
4774                     cs,
4775                     key,
4776                     &fa->Maximumlength);
4777 
4778                 ajStrDel(&key);
4779             }
4780 
4781             /* Use external Ensembl Sequence Region identifiers if present. */
4782 
4783             srids = ajStrNew();
4784 
4785             intsrid = ensSliceGetSeqregionIdentifier(slice);
4786 
4787             ajFmtPrintAppS(&srids, "%u, ", intsrid);
4788 
4789             while (1)
4790             {
4791                 extsrid = ensCoordsystemadaptorGetSeqregionidentifierExternal(
4792                     csa,
4793                     intsrid);
4794 
4795                 if (intsrid == extsrid)
4796                     break;
4797 
4798                 ajFmtPrintAppS(&srids, "%u, ", extsrid);
4799 
4800                 intsrid = extsrid;
4801             }
4802 
4803             /* Remove last comma and space. */
4804 
4805             ajStrCutEnd(&srids, 2);
4806 
4807             tmpconstr = ajStrNewS(constraint);
4808 
4809             if (ajStrGetLen(tmpconstr))
4810                 ajStrAppendC(&tmpconstr, " AND ");
4811 
4812             ajFmtPrintAppS(&tmpconstr,
4813                            "%s.seq_region_id IN (%S) AND ",
4814                            table,
4815                            srids);
4816 
4817             ajStrDel(&srids);
4818 
4819             if (fa->Startequalsend &&
4820                 (ensSliceGetStart(slice) == ensSliceGetEnd(slice)))
4821                 ajFmtPrintAppS(
4822                     &tmpconstr,
4823                     "%s.seq_region_start = %d "
4824                     "AND "
4825                     "%s.seq_region_end = %d",
4826                     table, ensSliceGetEnd(slice),
4827                     table, ensSliceGetStart(slice));
4828             else
4829             {
4830                 if (circular == ajFalse)
4831                 {
4832                     ajFmtPrintAppS(
4833                         &tmpconstr,
4834                         "%s.seq_region_start <= %d "
4835                         "AND "
4836                         "%s.seq_region_end >= %d",
4837                         table, ensSliceGetEnd(slice),
4838                         table, ensSliceGetStart(slice));
4839 
4840                     if (fa->Maximumlength != 0)
4841                         ajFmtPrintAppS(
4842                             &tmpconstr,
4843                             " AND "
4844                             "%s.seq_region_start >= %d",
4845                             table,
4846                             ensSliceGetStart(slice)
4847                             - fa->Maximumlength);
4848                 }
4849                 else
4850                 {
4851                     /* Deal with the case of a circular chromosome. */
4852 
4853                     if (ensSliceGetStart(slice) > ensSliceGetEnd(slice))
4854                         ajFmtPrintAppS(
4855                             &tmpconstr,
4856                             "("
4857                             "%s.seq_region_start >= %d "
4858                             "OR "
4859                             "%s.seq_region_start <= %d "
4860                             "OR "
4861                             "%s.seq_region_end >= %d "
4862                             "OR "
4863                             "%s.seq_region_end <= %d "
4864                             "OR "
4865                             "%s.seq_region_start > %s.seq_region_end"
4866                             ")",
4867                             table, ensSliceGetStart(slice),
4868                             table, ensSliceGetEnd(slice),
4869                             table, ensSliceGetStart(slice),
4870                             table, ensSliceGetEnd(slice),
4871                             table, table);
4872                     else
4873                         ajFmtPrintAppS(
4874                             &tmpconstr,
4875                             "("
4876                             "("
4877                             "%s.seq_region_start <= %d "
4878                             "AND "
4879                             "%s.seq_region_end >= %d"
4880                             ") "
4881                             "OR "
4882                             "("
4883                             "%s.seq_region_start > %s.seq_region_end "
4884                             "AND "
4885                             "("
4886                             "%s.seq_region_start <= %d "
4887                             "OR "
4888                             "%s.seq_region_end >= %d"
4889                             ")"
4890                             ")"
4891                             ")",
4892                             table, ensSliceGetEnd(slice),
4893                             table, ensSliceGetStart(slice),
4894                             table, table,
4895                             table, ensSliceGetEnd(slice),
4896                             table, ensSliceGetStart(slice));
4897                 }
4898             }
4899 
4900             pos = ajListNew();
4901 
4902             ensBaseadaptorFetchAllbyConstraint(
4903                 ba,
4904                 tmpconstr,
4905                 (EnsPAssemblymapper) NULL,
4906                 slice,
4907                 pos);
4908 
4909             /*
4910             ** Feature objects may still have to have coordinates made relative
4911             ** to the Slice start.
4912             */
4913 
4914             /*
4915             ** FIXME: The following mapper does not seem to be defined in the
4916             ** Perl API, when no mapping is needed. Why is there no error?
4917             ** _remap tests whether Ensembl Coordinate System objects are not
4918             ** equal and only executes the mapper code when the
4919             ** Ensembl Coordinate System objects are not equal, but that is
4920             ** exactly not the case when no mapping is required.
4921             */
4922 
4923             featureadaptorRemap(fa,
4924                                 pos,
4925                                 (EnsPAssemblymapper) NULL,
4926                                 slice);
4927 
4928             ajListPushlist(objects, &pos);
4929 
4930             ajStrDel(&tmpconstr);
4931         }
4932         else
4933         {
4934             /*
4935             ** Mapping is required as the Coordinate System objects of
4936             ** Ensembl Feature and Ensembl Slice differ.
4937             */
4938 
4939             ensAssemblymapperadaptorFetchByCoordsystems(
4940                 ama,
4941                 cs,
4942                 ensSliceGetCoordsystemObject(slice),
4943                 &am);
4944 
4945             if (!am)
4946             {
4947                 ensCoordsystemDel(&cs);
4948 
4949                 continue;
4950             }
4951 
4952             mrs = ajListNew();
4953 
4954             /*
4955             ** Get the list of coordinates and corresponding internal
4956             ** identifiers for the regions the Slice spans.
4957             */
4958 
4959             ensAssemblymapperMapSlice(am, slice, ajFalse, mrs);
4960 
4961             iter = ajListIterNew(mrs);
4962 
4963             while (!ajListIterDone(iter))
4964             {
4965                 mr = (EnsPMapperresult) ajListIterGet(iter);
4966 
4967                 /* Remove all Ensembl Mapper Results that represent gaps. */
4968 
4969                 if (ensMapperresultGetType(mr) == ensEMapperresultTypeGap)
4970                 {
4971                     ajListIterRemove(iter);
4972 
4973                     ensMapperresultDel(&mr);
4974                 }
4975             }
4976 
4977             ajListIterDel(&iter);
4978 
4979             mrslength = (ajuint) ajListGetLength(mrs);
4980 
4981             if (!mrslength)
4982             {
4983                 ensCoordsystemDel(&cs);
4984 
4985                 continue;
4986             }
4987 
4988             /*
4989             ** When regions are large and only partially spanned by a Slice
4990             ** it is faster to limit the query with start and end constraints.
4991             ** Take a simple approach and use regional constraints if there
4992             ** are less than a specific number of regions covered.
4993             */
4994 
4995             if (mrslength > featureadaptorKMaxSplitQuerySeqregions)
4996             {
4997                 tmpconstr = ajStrNewS(constraint);
4998 
4999                 if (ajStrGetLen(tmpconstr))
5000                     ajStrAppendC(&tmpconstr, " AND ");
5001 
5002                 srids = ajStrNew();
5003 
5004                 while (ajListPop(mrs, (void **) &mr))
5005                 {
5006                     ajFmtPrintAppS(&srids,
5007                                    "%u, ",
5008                                    ensMapperresultGetObjectidentifier(mr));
5009 
5010                     ensMapperresultDel(&mr);
5011                 }
5012 
5013                 /* Remove last comma and space. */
5014 
5015                 ajStrCutEnd(&srids, 2);
5016 
5017                 ajFmtPrintAppS(&tmpconstr,
5018                                "%s.seq_region_id IN (%S)",
5019                                table,
5020                                srids);
5021 
5022                 ajStrDel(&srids);
5023 
5024                 pos = ajListNew();
5025 
5026                 ensBaseadaptorFetchAllbyConstraint(
5027                     ba,
5028                     tmpconstr,
5029                     am,
5030                     slice,
5031                     pos);
5032 
5033                 featureadaptorRemap(fa, pos, am, slice);
5034 
5035                 ajListPushlist(objects, &pos);
5036 
5037                 ajStrDel(&tmpconstr);
5038             }
5039             else
5040             {
5041                 /*
5042                 ** Run multiple split queries using
5043                 ** start and end constraints.
5044                 */
5045 
5046                 if (!fa->Maximumlength)
5047                 {
5048                     key = ajStrNewC(table);
5049 
5050                     ensMetacoordinateadaptorRetrieveMaximumlength(
5051                         mca,
5052                         cs,
5053                         key,
5054                         &fa->Maximumlength);
5055 
5056                     ajStrDel(&key);
5057                 }
5058 
5059                 while (ajListPop(mrs, (void **) &mr))
5060                 {
5061                     tmpconstr = ajStrNewS(constraint);
5062 
5063                     if (ajStrGetLen(tmpconstr))
5064                         ajStrAppendC(&tmpconstr, " AND ");
5065 
5066                     ajFmtPrintAppS(&tmpconstr,
5067                                    "%s.seq_region_id = %u "
5068                                    "AND "
5069                                    "%s.seq_region_start <= %d "
5070                                    "AND "
5071                                    "%s.seq_region_end >= %d",
5072                                    table,
5073                                    ensMapperresultGetObjectidentifier(mr),
5074                                    table,
5075                                    ensMapperresultGetCoordinateStart(mr),
5076                                    table,
5077                                    ensMapperresultGetCoordinateEnd(mr));
5078 
5079                     if (fa->Maximumlength)
5080                         ajFmtPrintAppS(&tmpconstr,
5081                                        " AND "
5082                                        "%s.seq_region_start >= %d",
5083                                        table,
5084                                        ensMapperresultGetCoordinateStart(mr)
5085                                        - fa->Maximumlength);
5086 
5087                     pos = ajListNew();
5088 
5089                     ensBaseadaptorFetchAllbyConstraint(
5090                         ba,
5091                         tmpconstr,
5092                         am,
5093                         slice,
5094                         pos);
5095 
5096                     ajStrDel(&tmpconstr);
5097 
5098                     featureadaptorRemap(fa, pos, am, slice);
5099 
5100                     ajListPushlist(objects, &pos);
5101 
5102                     ensMapperresultDel(&mr);
5103                 }
5104             }
5105 
5106             ajListFree(&mrs);
5107 
5108             ensAssemblymapperDel(&am);
5109         }
5110 
5111         ensCoordsystemDel(&cs);
5112     }
5113 
5114     ajListFree(&css);
5115 
5116     return ajTrue;
5117 }
5118 
5119 
5120 
5121 
5122 /* @section object retrieval **************************************************
5123 **
5124 ** Functions for fetching Ensembl Feature objects from an
5125 ** Ensembl SQL database.
5126 **
5127 ** @fdata [EnsPFeatureadaptor]
5128 **
5129 ** @nam3rule Fetch Fetch Ensembl Feature object(s)
5130 ** @nam4rule All   Fetch all Ensembl Feature objects
5131 ** @nam4rule Allby Fetch all Ensembl Feature objects matching a criterion
5132 ** @nam5rule Analysisname Fetch all by an Ensembl Analysis name
5133 ** @nam5rule Slice Fetch by an Ensembl Slice
5134 ** @nam5rule Slicescore Fetch by an Ensembl Slice and a score
5135 ** @nam4rule By    Fetch one Ensembl Feature object matching a criterion
5136 **
5137 ** @argrule * fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
5138 ** @argrule FetchAll objects [AjPList] AJAX List of Ensembl Objects
5139 **                                     based on Ensembl Feature objects
5140 ** @argrule AllbyAnalysisname anname [const AjPStr] Ensembl Analysis name
5141 ** @argrule AllbyAnalysisname objects [AjPList] AJAX List of Ensembl Objects
5142 **                                              based on Ensembl Feature
5143 **                                              objects
5144 ** @argrule AllbySlice slice [EnsPSlice] Ensembl Slice
5145 ** @argrule AllbySlice constraint [const AjPStr] SQL constraint
5146 ** @argrule AllbySlice anname [const AjPStr] Ensembl Analysis name
5147 ** @argrule AllbySlice objects [AjPList] AJAX List of Ensembl Objects
5148 **                                       based on Ensembl Feature objects
5149 ** @argrule AllbySlicescore slice [EnsPSlice] Ensembl Slice
5150 ** @argrule AllbySlicescore score [double] Score
5151 ** @argrule AllbySlicescore anname [const AjPStr] Ensembl Analysis name
5152 ** @argrule AllbySlicescore objects [AjPList] AJAX List of Ensembl Objects
5153 **                                            based on Ensembl Feature objects
5154 **
5155 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
5156 **
5157 ** @fcategory use
5158 ******************************************************************************/
5159 
5160 
5161 
5162 
5163 /* @func ensFeatureadaptorFetchAllbyAnalysisname ******************************
5164 **
5165 ** Fetch all Ensembl Objects based on Ensembl Feature objects by an
5166 ** Ensembl Analysis name.
5167 **
5168 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_logic_name
5169 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
5170 ** @param [r] anname [const AjPStr] Ensembl Analysis name
5171 ** @param [u] objects [AjPList] AJAX List of Ensembl Objects based on
5172 **                              Ensembl Feature objects
5173 **
5174 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5175 **
5176 ** @release 6.4.0
5177 ** @@
5178 ******************************************************************************/
5179 
ensFeatureadaptorFetchAllbyAnalysisname(EnsPFeatureadaptor fa,const AjPStr anname,AjPList objects)5180 AjBool ensFeatureadaptorFetchAllbyAnalysisname(EnsPFeatureadaptor fa,
5181                                                const AjPStr anname,
5182                                                AjPList objects)
5183 {
5184     AjBool result = AJFALSE;
5185 
5186     AjPStr constraint = NULL;
5187 
5188     if (!fa)
5189         return ajFalse;
5190 
5191     if (!anname)
5192         return ajFalse;
5193 
5194     constraint = ajStrNew();
5195 
5196     if (!ensFeatureadaptorConstraintAppendAnalysisname(fa,
5197                                                        &constraint,
5198                                                        anname))
5199     {
5200         ajStrDel(&constraint);
5201 
5202         return ajFalse;
5203     }
5204 
5205     result = ensBaseadaptorFetchAllbyConstraint(
5206         ensFeatureadaptorGetBaseadaptor(fa),
5207         constraint,
5208         (EnsPAssemblymapper) NULL,
5209         (EnsPSlice) NULL,
5210         objects);
5211 
5212     ajStrDel(&constraint);
5213 
5214     return result;
5215 }
5216 
5217 
5218 
5219 
5220 /* @func ensFeatureadaptorFetchAllbySlice *************************************
5221 **
5222 ** Fetch all Ensembl Objects based on Ensembl Feature objects matching an
5223 ** SQL constraint on an Ensembl Slice.
5224 **
5225 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_Slice
5226 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_Slice_constraint
5227 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
5228 ** @param [u] slice [EnsPSlice] Ensembl Slice
5229 ** @param [rN] constraint [const AjPStr] SQL constraint
5230 ** @param [rN] anname [const AjPStr] Ensembl Analysis name
5231 ** @param [u] objects [AjPList] AJAX List of Ensembl Objects based on
5232 **                              Ensembl Feature objects
5233 **
5234 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5235 **
5236 ** @release 6.4.0
5237 ** @@
5238 ** NOTE: This implementation of the Ensembl Base Feature Adaptor does not
5239 ** cache Ensembl Feature objects indexed by complete SQL queries in their
5240 ** Slice context. The class polymorhism required to do this is difficult to
5241 ** implement in ANSI C. Additionally, SQL queries are cached by the RDBMS
5242 ** instance.
5243 ******************************************************************************/
5244 
ensFeatureadaptorFetchAllbySlice(EnsPFeatureadaptor fa,EnsPSlice slice,const AjPStr constraint,const AjPStr anname,AjPList objects)5245 AjBool ensFeatureadaptorFetchAllbySlice(EnsPFeatureadaptor fa,
5246                                         EnsPSlice slice,
5247                                         const AjPStr constraint,
5248                                         const AjPStr anname,
5249                                         AjPList objects)
5250 {
5251     ajint boundary = 0;
5252 
5253     ajuint srid   = 0U;
5254     ajuint pssrid = 0U;
5255 
5256     void *Pobject = NULL;
5257 
5258     AjBool debug = AJFALSE;
5259 
5260     AjIList ftiter = NULL;
5261     AjIList psiter = NULL;
5262 
5263     AjPList slpss = NULL; /* Slice Projection Segment objects */
5264     AjPList srpss = NULL; /* Sequence Region Projection Segment objects */
5265 
5266     AjPStr constr = NULL;
5267 
5268     EnsPDatabaseadaptor dba = NULL;
5269 
5270     EnsPFeature feature = NULL;
5271 
5272     EnsPProjectionsegment slps = NULL; /* Slice Projection Segment */
5273     EnsPProjectionsegment srps = NULL; /* Sequence Region Projection Segment */
5274 
5275     EnsPSlice psslice    = NULL;
5276     EnsPSlice srslice    = NULL;
5277     EnsPSliceadaptor sla = NULL;
5278 
5279     debug = ajDebugTest("ensFeatureadaptorFetchAllbySlice");
5280 
5281     if (debug)
5282     {
5283         ajDebug("ensFeatureadaptorFetchAllbySlice\n"
5284                 "  fa %p\n"
5285                 "  slice %p\n"
5286                 "  constraint '%S'\n"
5287                 "  anname '%S'\n"
5288                 "  objects %p\n",
5289                 fa,
5290                 slice,
5291                 constraint,
5292                 anname,
5293                 objects);
5294 
5295         ensSliceTrace(slice, 1);
5296     }
5297 
5298     if (!fa)
5299         return ajFalse;
5300 
5301     if (!slice)
5302         return ajFalse;
5303 
5304     if (!objects)
5305         return ajFalse;
5306 
5307     dba = ensFeatureadaptorGetDatabaseadaptor(fa);
5308 
5309     if (!dba)
5310     {
5311         ajDebug("ensFeatureadaptorFetchAllbySlice got an "
5312                 "Ensembl Feature Adaptor without an "
5313                 "Ensembl Database Adaptor.\n");
5314 
5315         return ajFalse;
5316     }
5317 
5318     if (constraint && ajStrGetLen(constraint))
5319         constr = ajStrNewS(constraint);
5320     else
5321         constr = ajStrNew();
5322 
5323     if (!ensFeatureadaptorConstraintAppendAnalysisname(fa, &constr, anname))
5324     {
5325         ajStrDel(&constr);
5326 
5327         return ajFalse;
5328     }
5329 
5330     /*
5331     ** Retrieve normalised, non-symlinked Slices to support pseudo-automsomal
5332     ** regions (PARs) and haplotypes (HAPs).
5333     */
5334 
5335     sla = ensRegistryGetSliceadaptor(dba);
5336 
5337     slpss = ajListNew();
5338 
5339     ensSliceadaptorRetrieveNormalisedprojection(sla, slice, slpss);
5340 
5341     if (!ajListGetLength(slpss))
5342         ajFatal("ensFeatureadaptorFetchAllbySlice could not get "
5343                 "normalised Slices. "
5344                 "The Ensembl Core database seems to contain incorrect "
5345                 "information in the 'assembly_exception' table.\n");
5346 
5347     /*
5348     ** Get Feature objects on the full original Slice, as well as any
5349     ** sym-linked Slice objects. Filter out partial Slice objects from
5350     ** Projection Segment objects that are based on the same Sequence Region
5351     ** as the original Slice. A Projection Segment representing the original
5352     ** Slice is added later on.
5353     */
5354 
5355     srid = ensSliceGetSeqregionIdentifier(slice);
5356 
5357     psiter = ajListIterNew(slpss);
5358 
5359     while (!ajListIterDone(psiter))
5360     {
5361         slps = (EnsPProjectionsegment) ajListIterGet(psiter);
5362 
5363         psslice = ensProjectionsegmentGetTargetSlice(slps);
5364 
5365         pssrid = ensSliceGetSeqregionIdentifier(psslice);
5366 
5367         if (pssrid == srid)
5368         {
5369             ajListIterRemove(psiter);
5370 
5371             ensProjectionsegmentDel(&slps);
5372         }
5373     }
5374 
5375     ajListIterDel(&psiter);
5376 
5377     /* Add back a Projection Segment representing the original Slice. */
5378 
5379     slps = ensProjectionsegmentNewIni(1, ensSliceCalculateLength(slice), slice);
5380 
5381     ajListPushAppend(slpss, (void *) slps);
5382 
5383     /*
5384     ** Construct an AJAX List of HAP and PAR boundaries for a Slice spanning
5385     ** the entire Sequence Region.
5386     */
5387 
5388     ensSliceadaptorFetchBySeqregionIdentifier(sla,
5389                                               srid,
5390                                               0,
5391                                               0,
5392                                               ensSliceGetStrand(slice),
5393                                               &srslice);
5394 
5395     srpss = ajListNew();
5396 
5397     ensSliceadaptorRetrieveNormalisedprojection(sla, srslice, srpss);
5398 
5399     ensSliceDel(&srslice);
5400 
5401     /*
5402     ** Exclude the first Projection Segment, since it indicates just the
5403     ** Slice start coordinate.
5404     **
5405     ** 'chromosome:NCBI36:c22_H2:1:49691432:1'
5406     **
5407     ** srcstart:srcend    trgslice
5408     **        1:40992945 'chromosome:NCBI36:22:1:40992945:1'
5409     ** 40992946:41056606 'chromosome:NCBI36:c22_H2:40992946:41056606:1'
5410     ** 41056607:49691432 'chromosome:NCBI36:22:41056607:49691432:1'
5411     */
5412 
5413     ajListPop(srpss, (void **) &srps);
5414 
5415     ensProjectionsegmentDel(&srps);
5416 
5417     /* Fetch Feature objects for the primary Slice and all symlinked Slices. */
5418 
5419     while (ajListPop(slpss, (void **) &slps))
5420     {
5421         featureadaptorSliceFetch(fa,
5422                                  ensProjectionsegmentGetTargetSlice(slps),
5423                                  constr,
5424                                  objects);
5425 
5426         if (!ensSliceMatch(slice, ensProjectionsegmentGetTargetSlice(slps)))
5427         {
5428             /*
5429             ** Feature objects returned on symlinked Slices need checking that
5430             ** they do not cross Slice boundaries.
5431             */
5432 
5433             /*
5434             ** FIXME: All Objects are pushed onto the same AJAX List and their
5435             ** Feature objects are rechecked further below. Should a separate
5436             ** AJAX List be used to fetch Objects for all Projection Segment
5437             ** Slices, then checked and pushed onto a separate AJAX List?
5438             */
5439 
5440             ftiter = ajListIterNew(objects);
5441 
5442             while (!ajListIterDone(ftiter))
5443             {
5444                 Pobject = ajListIterGet(ftiter);
5445 
5446                 feature = (*fa->FobjectGetFeature) (Pobject);
5447 
5448                 feature->Start += ensProjectionsegmentGetSourceStart(slps) - 1;
5449                 feature->End   += ensProjectionsegmentGetSourceStart(slps) - 1;
5450 
5451                 psiter = ajListIterNewread(srpss);
5452 
5453                 while (!ajListIterDone(psiter))
5454                 {
5455                     srps = (EnsPProjectionsegment) ajListIterGet(psiter);
5456 
5457                     boundary = ensProjectionsegmentGetSourceStart(srps) -
5458                         ensSliceGetStart(slice) + 1;
5459 
5460                     if ((feature->Start < boundary) &&
5461                         (feature->End >= boundary))
5462                     {
5463                         ajListIterRemove(ftiter);
5464 
5465                         if (debug)
5466                         {
5467                             ajDebug(
5468                                 "ensFeatureadaptorFetchAllbySlice "
5469                                 "got an Ensembl Object (%p), which "
5470                                 "Feature (%p) crosses the normalised Slice "
5471                                 "boundary at %d.\n",
5472                                 Pobject,
5473                                 feature,
5474                                 boundary);
5475 
5476                             ensFeatureTrace(feature, 1);
5477                         }
5478 
5479                         (*fa->Fdelete) (&Pobject);
5480 
5481                         feature = NULL;
5482 
5483                         break;
5484                     }
5485                 }
5486 
5487                 ajListIterDel(&psiter);
5488 
5489                 if (feature)
5490                     ensFeatureSetSlice(feature, slice);
5491             }
5492 
5493             ajListIterDel(&ftiter);
5494         }
5495 
5496         ensProjectionsegmentDel(&slps);
5497     }
5498 
5499     ajListFree(&slpss);
5500 
5501     while (ajListPop(srpss, (void **) &srps))
5502         ensProjectionsegmentDel(&srps);
5503 
5504     ajListFree(&srpss);
5505 
5506     ajStrDel(&constr);
5507 
5508     return ajTrue;
5509 }
5510 
5511 
5512 
5513 
5514 /* @func ensFeatureadaptorFetchAllbySlicescore ********************************
5515 **
5516 ** Fetch all Ensembl Objects based on Ensembl Feature objects on an
5517 ** Ensembl Slice above a threshold score.
5518 **
5519 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_Slice
5520 ** @param [u] fa [EnsPFeatureadaptor] Ensembl Feature Adaptor
5521 ** @param [u] slice [EnsPSlice] Ensembl Slice
5522 ** @param [r] score [double] Score
5523 ** @param [rN] anname [const AjPStr] Ensembl Analysis name
5524 ** @param [u] objects [AjPList] AJAX List of Ensembl Objects based on
5525 **                              Ensembl Feature objects
5526 **
5527 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5528 **
5529 ** @release 6.4.0
5530 ** @@
5531 ******************************************************************************/
5532 
ensFeatureadaptorFetchAllbySlicescore(EnsPFeatureadaptor fa,EnsPSlice slice,double score,const AjPStr anname,AjPList objects)5533 AjBool ensFeatureadaptorFetchAllbySlicescore(EnsPFeatureadaptor fa,
5534                                              EnsPSlice slice,
5535                                              double score,
5536                                              const AjPStr anname,
5537                                              AjPList objects)
5538 {
5539     const char *table = NULL;
5540 
5541     AjBool result = AJFALSE;
5542 
5543     AjPStr constraint = NULL;
5544 
5545     if (!fa)
5546         return ajFalse;
5547 
5548     if (!slice)
5549         return ajFalse;
5550 
5551     if (!objects)
5552         return ajFalse;
5553 
5554     table = ensBaseadaptorGetPrimarytable(
5555         ensFeatureadaptorGetBaseadaptor(fa));
5556 
5557     constraint = ajFmtStr("%s.score > %f", table, score);
5558 
5559     result = ensFeatureadaptorFetchAllbySlice(
5560         fa,
5561         slice,
5562         constraint,
5563         anname,
5564         objects);
5565 
5566     ajStrDel(&constraint);
5567 
5568     return result;
5569 }
5570 
5571 
5572 
5573 
5574 /* @datasection [EnsPFeaturepair] Ensembl Feature Pair ************************
5575 **
5576 ** @nam2rule Featurepair Functions for manipulating
5577 ** Ensembl Feature Pair objects
5578 **
5579 ** @cc Bio::EnsEMBL::FeaturePair
5580 ** @cc CVS Revision: 1.68
5581 ** @cc CVS Tag: branch-ensembl-68
5582 **
5583 ******************************************************************************/
5584 
5585 
5586 
5587 
5588 /* @section constructors ******************************************************
5589 **
5590 ** All constructors return a new Ensembl Feature Pair by pointer.
5591 ** It is the responsibility of the user to first destroy any previous
5592 ** Feature Pair. The target pointer does not need to be initialised to
5593 ** NULL, but it is good programming practice to do so anyway.
5594 **
5595 ** @fdata [EnsPFeaturepair]
5596 **
5597 ** @nam3rule New Constructor
5598 ** @nam4rule Cpy Constructor with existing object
5599 ** @nam4rule Ini Constructor with initial values
5600 ** @nam4rule Ref Constructor by incrementing the reference counter
5601 **
5602 ** @argrule Cpy fp [const EnsPFeaturepair] Ensembl Feature Pair
5603 ** @argrule Ini srcfeature [EnsPFeature] Source Ensembl Feature
5604 ** @argrule Ini trgfeature [EnsPFeature] Target Ensembl Feature
5605 ** @argrule Ini edb [EnsPExternaldatabase] Ensembl External Database
5606 ** @argrule Ini extra [AjPStr] Extra data
5607 ** @argrule Ini srcspecies [AjPStr] Source species name
5608 ** @argrule Ini trgspecies [AjPStr] Target species name
5609 ** @argrule Ini groupid [ajuint] Group id
5610 ** @argrule Ini levelid [ajuint] Level id
5611 ** @argrule Ini evalue [double] e- or p-value
5612 ** @argrule Ini score [double] Score
5613 ** @argrule Ini srccoverage [float] Source coverage in percent
5614 ** @argrule Ini trgcoverage [float] Target coverage in percent
5615 ** @argrule Ini identity [float] Sequence identity in percent
5616 ** @argrule Ref fp [EnsPFeaturepair] Ensembl Feature Pair
5617 **
5618 ** @valrule * [EnsPFeaturepair] Ensembl Feature Pair or NULL
5619 **
5620 ** @fcategory new
5621 ******************************************************************************/
5622 
5623 
5624 
5625 
5626 /* @func ensFeaturepairNewCpy *************************************************
5627 **
5628 ** Object-based constructor function, which returns an independent object.
5629 **
5630 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5631 **
5632 ** @return [EnsPFeaturepair] Ensembl Feature Pair or NULL
5633 **
5634 ** @release 6.4.0
5635 ** @@
5636 ******************************************************************************/
5637 
ensFeaturepairNewCpy(const EnsPFeaturepair fp)5638 EnsPFeaturepair ensFeaturepairNewCpy(const EnsPFeaturepair fp)
5639 {
5640     EnsPFeaturepair pthis = NULL;
5641 
5642     if (!fp)
5643         return NULL;
5644 
5645     AJNEW0(pthis);
5646 
5647     pthis->SourceFeature    = ensFeatureNewRef(fp->SourceFeature);
5648     pthis->TargetFeature    = ensFeatureNewRef(fp->TargetFeature);
5649     pthis->Externaldatabase = ensExternaldatabaseNewRef(fp->Externaldatabase);
5650 
5651     if (fp->Extradata)
5652         pthis->Extradata = ajStrNewRef(fp->Extradata);
5653 
5654     if (fp->SourceSpecies)
5655         pthis->SourceSpecies = ajStrNewRef(fp->SourceSpecies);
5656 
5657     if (fp->TargetSpecies)
5658         pthis->TargetSpecies = ajStrNewRef(fp->TargetSpecies);
5659 
5660     pthis->Use             = 1U;
5661     pthis->Evalue          = fp->Evalue;
5662     pthis->Score           = fp->Score;
5663     pthis->Groupidentifier = fp->Groupidentifier;
5664     pthis->Levelidentifier = fp->Levelidentifier;
5665     pthis->SourceCoverage  = fp->SourceCoverage;
5666     pthis->TargetCoverage  = fp->TargetCoverage;
5667 
5668     return pthis;
5669 }
5670 
5671 
5672 
5673 
5674 /* @func ensFeaturepairNewIni *************************************************
5675 **
5676 ** Constructor of an Ensembl Feature Pair with initial values.
5677 **
5678 ** @cc Bio::EnsEMBL::Feature::new
5679 ** @param [u] srcfeature [EnsPFeature] Source Ensembl Feature
5680 ** @cc Bio::EnsEMBL::FeaturePair::new
5681 ** @param [u] trgfeature [EnsPFeature] Target Ensembl Feature
5682 ** @param [u] edb [EnsPExternaldatabase] Ensembl External Database
5683 ** @param [u] extra [AjPStr] Extra data
5684 ** @param [u] srcspecies [AjPStr] Source species name
5685 ** @param [u] trgspecies [AjPStr] Target species name
5686 ** @param [r] groupid [ajuint] Group id
5687 ** @param [r] levelid [ajuint] Level id
5688 ** @param [r] evalue [double] e- or p-value
5689 ** @param [r] score [double] Score
5690 ** @param [r] srccoverage [float] Source coverage in percent
5691 ** @param [r] trgcoverage [float] Target coverage in percent
5692 ** @param [r] identity [float] Sequence identity in percent
5693 **
5694 ** @return [EnsPFeaturepair] Ensembl Feature Pair or NULL
5695 **
5696 ** @release 6.4.0
5697 ** @@
5698 ******************************************************************************/
5699 
ensFeaturepairNewIni(EnsPFeature srcfeature,EnsPFeature trgfeature,EnsPExternaldatabase edb,AjPStr extra,AjPStr srcspecies,AjPStr trgspecies,ajuint groupid,ajuint levelid,double evalue,double score,float srccoverage,float trgcoverage,float identity)5700 EnsPFeaturepair ensFeaturepairNewIni(EnsPFeature srcfeature,
5701                                      EnsPFeature trgfeature,
5702                                      EnsPExternaldatabase edb,
5703                                      AjPStr extra,
5704                                      AjPStr srcspecies,
5705                                      AjPStr trgspecies,
5706                                      ajuint groupid,
5707                                      ajuint levelid,
5708                                      double evalue,
5709                                      double score,
5710                                      float srccoverage,
5711                                      float trgcoverage,
5712                                      float identity)
5713 {
5714     EnsPFeaturepair fp = NULL;
5715 
5716     if (!srcfeature)
5717         return NULL;
5718 
5719     if (!trgfeature)
5720         return NULL;
5721 
5722     AJNEW0(fp);
5723 
5724     fp->SourceFeature = ensFeatureNewRef(srcfeature);
5725 
5726     fp->TargetFeature = ensFeatureNewRef(trgfeature);
5727 
5728     fp->Externaldatabase = ensExternaldatabaseNewRef(edb);
5729 
5730     if (extra)
5731         fp->Extradata = ajStrNewRef(extra);
5732 
5733     if (srcspecies)
5734         fp->SourceSpecies = ajStrNewRef(srcspecies);
5735 
5736     if (trgspecies)
5737         fp->TargetSpecies = ajStrNewRef(trgspecies);
5738 
5739     fp->Use             = 1U;
5740     fp->Evalue          = evalue;
5741     fp->Score           = score;
5742     fp->Groupidentifier = groupid;
5743     fp->Levelidentifier = levelid;
5744     fp->SourceCoverage  = srccoverage;
5745     fp->TargetCoverage  = trgcoverage;
5746     fp->Identity        = identity;
5747 
5748     return fp;
5749 }
5750 
5751 
5752 
5753 
5754 /* @func ensFeaturepairNewRef *************************************************
5755 **
5756 ** Ensembl Object referencing function, which returns a pointer to the
5757 ** Ensembl Object passed in and increases its reference count.
5758 **
5759 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
5760 **
5761 ** @return [EnsPFeaturepair] Ensembl Feature Pair or NULL
5762 **
5763 ** @release 6.2.0
5764 ** @@
5765 ******************************************************************************/
5766 
ensFeaturepairNewRef(EnsPFeaturepair fp)5767 EnsPFeaturepair ensFeaturepairNewRef(EnsPFeaturepair fp)
5768 {
5769     if (!fp)
5770         return NULL;
5771 
5772     fp->Use++;
5773 
5774     return fp;
5775 }
5776 
5777 
5778 
5779 
5780 /* @section destructors *******************************************************
5781 **
5782 ** Destruction destroys all internal data structures and frees the memory
5783 ** allocated for an Ensembl Feature Pair object.
5784 **
5785 ** @fdata [EnsPFeaturepair]
5786 **
5787 ** @nam3rule Del Destroy (free) an Ensembl Feature Pair
5788 **
5789 ** @argrule * Pfp [EnsPFeaturepair*] Ensembl Feature Pair address
5790 **
5791 ** @valrule * [void]
5792 **
5793 ** @fcategory delete
5794 ******************************************************************************/
5795 
5796 
5797 
5798 
5799 /* @func ensFeaturepairDel ****************************************************
5800 **
5801 ** Default destructor for an Ensembl Feature Pair.
5802 **
5803 ** @param [d] Pfp [EnsPFeaturepair*] Ensembl Feature Pair address
5804 **
5805 ** @return [void]
5806 **
5807 ** @release 6.2.0
5808 ** @@
5809 ******************************************************************************/
5810 
ensFeaturepairDel(EnsPFeaturepair * Pfp)5811 void ensFeaturepairDel(EnsPFeaturepair *Pfp)
5812 {
5813     EnsPFeaturepair pthis = NULL;
5814 
5815     if (!Pfp)
5816         return;
5817 
5818 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
5819     if (ajDebugTest("ensFeaturepairDel"))
5820     {
5821         ajDebug("ensFeaturepairDel\n"
5822                 "  *Pfp %p\n",
5823                 *Pfp);
5824 
5825         ensFeaturepairTrace(*Pfp, 1);
5826     }
5827 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
5828 
5829     if (!(pthis = *Pfp) || --pthis->Use)
5830     {
5831         *Pfp = NULL;
5832 
5833         return;
5834     }
5835 
5836     ensFeatureDel(&pthis->SourceFeature);
5837     ensFeatureDel(&pthis->TargetFeature);
5838 
5839     ensExternaldatabaseDel(&pthis->Externaldatabase);
5840 
5841     ajStrDel(&pthis->Extradata);
5842     ajStrDel(&pthis->SourceSpecies);
5843     ajStrDel(&pthis->TargetSpecies);
5844 
5845     ajMemFree((void **) Pfp);
5846 
5847     return;
5848 }
5849 
5850 
5851 
5852 
5853 /* @section member retrieval **************************************************
5854 **
5855 ** Functions for returning members of an Ensembl Feature Pair object.
5856 **
5857 ** @fdata [EnsPFeaturepair]
5858 **
5859 ** @nam3rule Get Return Feature Pair attribute(s)
5860 ** @nam4rule Evalue Return the e-value
5861 ** @nam4rule Externaldatabase Return the Ensembl External Database
5862 ** @nam4rule Extradata Return the extra data
5863 ** @nam4rule Groupidentifier Return the group identifier
5864 ** @nam4rule Identity Return the sequence identity
5865 ** @nam4rule Levelidentifier Return the level identifier
5866 ** @nam4rule Score Return the score
5867 ** @nam4rule Source Return source member(s)
5868 ** @nam5rule SourceCoverage Return the source coverage
5869 ** @nam5rule SourceFeature Return the source Ensembl Feature
5870 ** @nam5rule SourceSpecies Return the source species name
5871 ** @nam4rule Target Return target member(s)
5872 ** @nam5rule TargetCoverage Return the target coverage
5873 ** @nam5rule TargetFeature Return the target Ensembl Feature
5874 ** @nam5rule TargetSpecies Return the target species name
5875 **
5876 ** @argrule * fp [const EnsPFeaturepair] Feature Pair
5877 **
5878 ** @valrule Evalue [double] E-value or 0.0
5879 ** @valrule Externaldatabase [EnsPExternaldatabase] Ensembl External Database
5880 ** or NULL
5881 ** @valrule Extradata [AjPStr] Extra data or NULL
5882 ** @valrule Groupidentifier [ajuint] Group identifier or 0U
5883 ** @valrule Identity [float] Sequence identity od 0.0F
5884 ** @valrule Levelidentifier [ajuint] Level identifier or 0U
5885 ** @valrule Score [double] Score or 0.0
5886 ** @valrule SourceCoverage [float] Source coverage or 0.0F
5887 ** @valrule SourceFeature [EnsPFeature] Source Ensembl Feature or NULL
5888 ** @valrule SourceSpecies [AjPStr] Source species name or NULL
5889 ** @valrule TargetCoverage [float] Target coverage or 0.0F
5890 ** @valrule TargetFeature [EnsPFeature] Target Ensembl Feature or NULL
5891 ** @valrule TargetSpecies [AjPStr] Target species name or NULL
5892 **
5893 ** @fcategory use
5894 ******************************************************************************/
5895 
5896 
5897 
5898 
5899 /* @func ensFeaturepairGetEvalue **********************************************
5900 **
5901 ** Get the e-value member of an Ensembl Feature Pair.
5902 **
5903 ** @cc Bio::EnsEMBL::FeaturePair::p_value
5904 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5905 **
5906 ** @return [double] E-value or 0.0
5907 **
5908 ** @release 6.2.0
5909 ** @@
5910 ******************************************************************************/
5911 
ensFeaturepairGetEvalue(const EnsPFeaturepair fp)5912 double ensFeaturepairGetEvalue(
5913     const EnsPFeaturepair fp)
5914 {
5915     return (fp) ? fp->Evalue : 0.0;
5916 }
5917 
5918 
5919 
5920 
5921 /* @func ensFeaturepairGetExternaldatabase ************************************
5922 **
5923 ** Get the Ensembl External Database member of an Ensembl Feature Pair.
5924 **
5925 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5926 **
5927 ** @return [EnsPExternaldatabase] Ensembl External Database or NULL
5928 **
5929 ** @release 6.2.0
5930 ** @@
5931 ******************************************************************************/
5932 
ensFeaturepairGetExternaldatabase(const EnsPFeaturepair fp)5933 EnsPExternaldatabase ensFeaturepairGetExternaldatabase(
5934     const EnsPFeaturepair fp)
5935 {
5936     return (fp) ? fp->Externaldatabase : NULL;
5937 }
5938 
5939 
5940 
5941 
5942 /* @func ensFeaturepairGetExtradata *******************************************
5943 **
5944 ** Get the extra data member of an Ensembl Feature Pair.
5945 **
5946 ** @cc Bio::EnsEMBL::FeaturePair::extra_data
5947 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5948 **
5949 ** @return [AjPStr] Extra data or NULL
5950 **
5951 ** @release 6.4.0
5952 ** @@
5953 ******************************************************************************/
5954 
ensFeaturepairGetExtradata(const EnsPFeaturepair fp)5955 AjPStr ensFeaturepairGetExtradata(
5956     const EnsPFeaturepair fp)
5957 {
5958     return (fp) ? fp->Extradata : NULL;
5959 }
5960 
5961 
5962 
5963 
5964 /* @func ensFeaturepairGetGroupidentifier *************************************
5965 **
5966 ** Get the group identifier member of an Ensembl Feature Pair.
5967 **
5968 ** @cc Bio::EnsEMBL::FeaturePair::group_id
5969 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5970 **
5971 ** @return [ajuint] Group identifier or 0U
5972 **
5973 ** @release 6.4.0
5974 ** @@
5975 ******************************************************************************/
5976 
ensFeaturepairGetGroupidentifier(const EnsPFeaturepair fp)5977 ajuint ensFeaturepairGetGroupidentifier(
5978     const EnsPFeaturepair fp)
5979 {
5980     return (fp) ? fp->Groupidentifier : 0U;
5981 }
5982 
5983 
5984 
5985 
5986 /* @func ensFeaturepairGetIdentity ********************************************
5987 **
5988 ** Get the sequence identity member of an Ensembl Feature Pair.
5989 **
5990 ** @cc Bio::EnsEMBL::FeaturePair::percent_id
5991 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
5992 **
5993 ** @return [float] Sequence identity or 0.0F
5994 **
5995 ** @release 6.4.0
5996 ** @@
5997 ******************************************************************************/
5998 
ensFeaturepairGetIdentity(const EnsPFeaturepair fp)5999 float ensFeaturepairGetIdentity(
6000     const EnsPFeaturepair fp)
6001 {
6002     return (fp) ? fp->Identity : 0.0F;
6003 }
6004 
6005 
6006 
6007 
6008 /* @func ensFeaturepairGetLevelidentifier *************************************
6009 **
6010 ** Get the level identifier member of an Ensembl Feature Pair.
6011 **
6012 ** @cc Bio::EnsEMBL::FeaturePair::level_id
6013 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6014 **
6015 ** @return [ajuint] Level identifier or 0U
6016 **
6017 ** @release 6.4.0
6018 ** @@
6019 ******************************************************************************/
6020 
ensFeaturepairGetLevelidentifier(const EnsPFeaturepair fp)6021 ajuint ensFeaturepairGetLevelidentifier(
6022     const EnsPFeaturepair fp)
6023 {
6024     return (fp) ? fp->Levelidentifier : 0U;
6025 }
6026 
6027 
6028 
6029 
6030 /* @func ensFeaturepairGetScore ***********************************************
6031 **
6032 ** Get the score member of an Ensembl Feature Pair.
6033 **
6034 ** @cc Bio::EnsEMBL::FeaturePair::score
6035 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6036 **
6037 ** @return [double] Score or 0.0
6038 **
6039 ** @release 6.2.0
6040 ** @@
6041 ******************************************************************************/
6042 
ensFeaturepairGetScore(const EnsPFeaturepair fp)6043 double ensFeaturepairGetScore(
6044     const EnsPFeaturepair fp)
6045 {
6046     return (fp) ? fp->Evalue : 0.0;
6047 }
6048 
6049 
6050 
6051 
6052 /* @func ensFeaturepairGetSourceCoverage **************************************
6053 **
6054 ** Get the source coverage member of an Ensembl Feature Pair.
6055 **
6056 ** @cc Bio::EnsEMBL::FeaturePair::coverage
6057 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6058 **
6059 ** @return [float] Source coverage or 0.0F
6060 **
6061 ** @release 6.2.0
6062 ** @@
6063 ******************************************************************************/
6064 
ensFeaturepairGetSourceCoverage(const EnsPFeaturepair fp)6065 float ensFeaturepairGetSourceCoverage(
6066     const EnsPFeaturepair fp)
6067 {
6068     return (fp) ? fp->SourceCoverage : 0.0F;
6069 }
6070 
6071 
6072 
6073 
6074 /* @func ensFeaturepairGetSourceFeature ***************************************
6075 **
6076 ** Get the source Ensembl Feature member of an Ensembl Feature Pair.
6077 **
6078 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6079 **
6080 ** @return [EnsPFeature] Source Ensembl Feature or NULL
6081 **
6082 ** @release 6.2.0
6083 ** @@
6084 ******************************************************************************/
6085 
ensFeaturepairGetSourceFeature(const EnsPFeaturepair fp)6086 EnsPFeature ensFeaturepairGetSourceFeature(
6087     const EnsPFeaturepair fp)
6088 {
6089     return (fp) ? fp->SourceFeature : NULL;
6090 }
6091 
6092 
6093 
6094 
6095 /* @func ensFeaturepairGetSourceSpecies ***************************************
6096 **
6097 ** Get the source species name member of an Ensembl Feature Pair.
6098 **
6099 ** @cc Bio::EnsEMBL::FeaturePair::species
6100 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6101 **
6102 ** @return [AjPStr] Source species or NULL
6103 **
6104 ** @release 6.2.0
6105 ** @@
6106 ******************************************************************************/
6107 
ensFeaturepairGetSourceSpecies(const EnsPFeaturepair fp)6108 AjPStr ensFeaturepairGetSourceSpecies(
6109     const EnsPFeaturepair fp)
6110 {
6111     return (fp) ? fp->SourceSpecies : NULL;
6112 }
6113 
6114 
6115 
6116 
6117 /* @func ensFeaturepairGetTargetCoverage **************************************
6118 **
6119 ** Get the target coverage member of an Ensembl Feature Pair.
6120 **
6121 ** @cc Bio::EnsEMBL::FeaturePair::hcoverage
6122 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6123 **
6124 ** @return [float] Target coverage or 0.0F
6125 **
6126 ** @release 6.2.0
6127 ** @@
6128 ******************************************************************************/
6129 
ensFeaturepairGetTargetCoverage(const EnsPFeaturepair fp)6130 float ensFeaturepairGetTargetCoverage(
6131     const EnsPFeaturepair fp)
6132 {
6133     return (fp) ? fp->TargetCoverage : 0.0F;
6134 }
6135 
6136 
6137 
6138 
6139 /* @func ensFeaturepairGetTargetFeature ***************************************
6140 **
6141 ** Get the target Ensembl Feature member of an Ensembl Feature Pair.
6142 **
6143 ** @cc Bio::EnsEMBL::FeaturePair::hslice
6144 ** @cc Bio::EnsEMBL::FeaturePair::hseqname
6145 ** @cc Bio::EnsEMBL::FeaturePair::hstart
6146 ** @cc Bio::EnsEMBL::FeaturePair::hend
6147 ** @cc Bio::EnsEMBL::FeaturePair::hstrand
6148 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6149 **
6150 ** @return [EnsPFeature] Target Ensembl Feature or NULL
6151 **
6152 ** @release 6.2.0
6153 ** @@
6154 ******************************************************************************/
6155 
ensFeaturepairGetTargetFeature(const EnsPFeaturepair fp)6156 EnsPFeature ensFeaturepairGetTargetFeature(
6157     const EnsPFeaturepair fp)
6158 {
6159     return (fp) ? fp->TargetFeature : NULL;
6160 }
6161 
6162 
6163 
6164 
6165 /* @func ensFeaturepairGetTargetSpecies ***************************************
6166 **
6167 ** Get the target species name member of an Ensembl Feature Pair.
6168 **
6169 ** @cc Bio::EnsEMBL::FeaturePair::hspecies
6170 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6171 **
6172 ** @return [AjPStr] Target species or NULL
6173 **
6174 ** @release 6.2.0
6175 ** @@
6176 ******************************************************************************/
6177 
ensFeaturepairGetTargetSpecies(const EnsPFeaturepair fp)6178 AjPStr ensFeaturepairGetTargetSpecies(
6179     const EnsPFeaturepair fp)
6180 {
6181     return (fp) ? fp->TargetSpecies : NULL;
6182 }
6183 
6184 
6185 
6186 
6187 /* @section member assignment *************************************************
6188 **
6189 ** Functions for assigning members of an Ensembl Feature Pair object.
6190 **
6191 ** @fdata [EnsPFeaturepair]
6192 **
6193 ** @nam3rule Set Set one member of an Ensembl Feature Pair
6194 ** @nam4rule Evalue Set the e-value
6195 ** @nam4rule Externaldatabase Set the Ensembl External Database
6196 ** @nam4rule Extradata Set the extra data
6197 ** @nam4rule Identity Set the sequence identity
6198 ** @nam4rule Groupidentifier Set the group identifier
6199 ** @nam4rule Levelidentifier Set the level identifier
6200 ** @nam4rule Score Set the score
6201 ** @nam4rule Source Set source member(s)
6202 ** @nam5rule SourceCoverage Set the source coverage
6203 ** @nam5rule SourceFeature Set the source Ensembl Feature
6204 ** @nam5rule SourceSpecies Set the source species name
6205 ** @nam4rule Target Set target member(s)
6206 ** @nam5rule TargetCoverage Set the target coverage
6207 ** @nam5rule TargetFeature Set the target Ensembl Feature
6208 ** @nam5rule TargetSpecies Set the target species name
6209 **
6210 ** @argrule * fp [EnsPFeaturepair] Ensembl Feature Pair object
6211 ** @argrule Evalue evalue [double] E-value
6212 ** @argrule Externaldatabase edb [EnsPExternaldatabase]
6213 ** Ensembl External Database
6214 ** @argrule Extradata extra [AjPStr] Extra data
6215 ** @argrule Groupidentifier groupid [ajuint] Group identifier
6216 ** @argrule Identity identity [float] Sequence identity
6217 ** @argrule Levelidentifier levelid [ajuint] Level identifier
6218 ** @argrule Score score [double] Score
6219 ** @argrule SourceCoverage coverage [float] Source coverage
6220 ** @argrule SourceFeature feature [EnsPFeature] Source Ensembl Feature
6221 ** @argrule SourceSpecies species [AjPStr] Source species
6222 ** @argrule TargetCoverage coverage [float] Target coverage
6223 ** @argrule TargetFeature feature [EnsPFeature] Target Ensembl Feature
6224 ** @argrule TargetSpecies tspecies [AjPStr] Target species
6225 **
6226 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
6227 **
6228 ** @fcategory modify
6229 ******************************************************************************/
6230 
6231 
6232 
6233 
6234 /* @func ensFeaturepairSetEvalue **********************************************
6235 **
6236 ** Set the e-value member of an Ensembl Feature Pair.
6237 **
6238 ** @cc Bio::EnsEMBL::FeaturePair::p_value
6239 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6240 ** @param [r] evalue [double] E-value
6241 **
6242 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6243 **
6244 ** @release 6.2.0
6245 ** @@
6246 ******************************************************************************/
6247 
ensFeaturepairSetEvalue(EnsPFeaturepair fp,double evalue)6248 AjBool ensFeaturepairSetEvalue(EnsPFeaturepair fp,
6249                                double evalue)
6250 {
6251     if (!fp)
6252         return ajFalse;
6253 
6254     fp->Evalue = evalue;
6255 
6256     return ajTrue;
6257 }
6258 
6259 
6260 
6261 
6262 /* @func ensFeaturepairSetExternaldatabase ************************************
6263 **
6264 ** Set the Ensembl External Database member of an Ensembl Feature Pair.
6265 **
6266 ** @cc Bio::EnsEMBL::FeaturePair::external_db_id
6267 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6268 ** @param [u] edb [EnsPExternaldatabase] Ensembl External Database
6269 **
6270 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6271 **
6272 ** @release 6.2.0
6273 ** @@
6274 ******************************************************************************/
6275 
ensFeaturepairSetExternaldatabase(EnsPFeaturepair fp,EnsPExternaldatabase edb)6276 AjBool ensFeaturepairSetExternaldatabase(EnsPFeaturepair fp,
6277                                          EnsPExternaldatabase edb)
6278 {
6279     if (!fp)
6280         return ajFalse;
6281 
6282     ensExternaldatabaseDel(&fp->Externaldatabase);
6283 
6284     fp->Externaldatabase = ensExternaldatabaseNewRef(edb);
6285 
6286     return ajTrue;
6287 }
6288 
6289 
6290 
6291 
6292 /* @func ensFeaturepairSetExtradata *******************************************
6293 **
6294 ** Set the extra data member of an Ensembl Feature Pair.
6295 **
6296 ** @cc Bio::EnsEMBL::FeaturePair::extra_data
6297 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6298 ** @param [u] extra [AjPStr] Extra data
6299 **
6300 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6301 **
6302 ** @release 6.4.0
6303 ** @@
6304 ******************************************************************************/
6305 
ensFeaturepairSetExtradata(EnsPFeaturepair fp,AjPStr extra)6306 AjBool ensFeaturepairSetExtradata(EnsPFeaturepair fp,
6307                                   AjPStr extra)
6308 {
6309     if (!fp)
6310         return ajFalse;
6311 
6312     ajStrDel(&fp->Extradata);
6313 
6314     if (extra)
6315         fp->Extradata = ajStrNewRef(extra);
6316 
6317     return ajTrue;
6318 }
6319 
6320 
6321 
6322 
6323 /* @func ensFeaturepairSetGroupidentifier *************************************
6324 **
6325 ** Set the group identifier member of an Ensembl Feature Pair.
6326 **
6327 ** @cc Bio::EnsEMBL::FeaturePair::group_id
6328 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6329 ** @param [r] groupid [ajuint] Group identifier
6330 **
6331 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6332 **
6333 ** @release 6.4.0
6334 ** @@
6335 ******************************************************************************/
6336 
ensFeaturepairSetGroupidentifier(EnsPFeaturepair fp,ajuint groupid)6337 AjBool ensFeaturepairSetGroupidentifier(EnsPFeaturepair fp,
6338                                         ajuint groupid)
6339 {
6340     if (!fp)
6341         return ajFalse;
6342 
6343     fp->Groupidentifier = groupid;
6344 
6345     return ajTrue;
6346 }
6347 
6348 
6349 
6350 
6351 /* @func ensFeaturepairSetIdentity ********************************************
6352 **
6353 ** Set the sequence identity member of an Ensembl Feature Pair.
6354 **
6355 ** @cc Bio::EnsEMBL::FeaturePair::percent_id
6356 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6357 ** @param [r] identity [float] Sequence identity
6358 **
6359 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6360 **
6361 ** @release 6.4.0
6362 ** @@
6363 ******************************************************************************/
6364 
ensFeaturepairSetIdentity(EnsPFeaturepair fp,float identity)6365 AjBool ensFeaturepairSetIdentity(EnsPFeaturepair fp,
6366                                  float identity)
6367 {
6368     if (!fp)
6369         return ajFalse;
6370 
6371     fp->Identity = identity;
6372 
6373     return ajTrue;
6374 }
6375 
6376 
6377 
6378 
6379 /* @func ensFeaturepairSetLevelidentifier *************************************
6380 **
6381 ** Set the level identifier member of an Ensembl Feature Pair.
6382 **
6383 ** @cc Bio::EnsEMBL::FeaturePair::level_id
6384 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6385 ** @param [r] levelid [ajuint] Level identifier
6386 **
6387 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6388 **
6389 ** @release 6.4.0
6390 ** @@
6391 ******************************************************************************/
6392 
ensFeaturepairSetLevelidentifier(EnsPFeaturepair fp,ajuint levelid)6393 AjBool ensFeaturepairSetLevelidentifier(EnsPFeaturepair fp,
6394                                         ajuint levelid)
6395 {
6396     if (!fp)
6397         return ajFalse;
6398 
6399     fp->Levelidentifier = levelid;
6400 
6401     return ajTrue;
6402 }
6403 
6404 
6405 
6406 
6407 /* @func ensFeaturepairSetScore ***********************************************
6408 **
6409 ** Set the score member of an Ensembl Feature Pair.
6410 **
6411 ** @cc Bio::EnsEMBL::FeaturePair::score
6412 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6413 ** @param [r] score [double] Score
6414 **
6415 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6416 **
6417 ** @release 6.2.0
6418 ** @@
6419 ******************************************************************************/
6420 
ensFeaturepairSetScore(EnsPFeaturepair fp,double score)6421 AjBool ensFeaturepairSetScore(EnsPFeaturepair fp,
6422                               double score)
6423 {
6424     if (!fp)
6425         return ajFalse;
6426 
6427     fp->Score = score;
6428 
6429     return ajTrue;
6430 }
6431 
6432 
6433 
6434 
6435 /* @func ensFeaturepairSetSourceCoverage **************************************
6436 **
6437 ** Set the source coverage member of an Ensembl Feature Pair.
6438 **
6439 ** @cc Bio::EnsEMBL::FeaturePair::coverage
6440 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6441 ** @param [r] coverage [float] Source coverage
6442 **
6443 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6444 **
6445 ** @release 6.2.0
6446 ** @@
6447 ******************************************************************************/
6448 
ensFeaturepairSetSourceCoverage(EnsPFeaturepair fp,float coverage)6449 AjBool ensFeaturepairSetSourceCoverage(EnsPFeaturepair fp,
6450                                        float coverage)
6451 {
6452     if (!fp)
6453         return ajFalse;
6454 
6455     fp->SourceCoverage = coverage;
6456 
6457     return ajTrue;
6458 }
6459 
6460 
6461 
6462 
6463 /* @func ensFeaturepairSetSourceFeature ***************************************
6464 **
6465 ** Set the source Ensembl Feature member of an Ensembl Feature Pair.
6466 **
6467 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6468 ** @param [u] feature [EnsPFeature] Source Ensembl Feature
6469 **
6470 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6471 **
6472 ** @release 6.2.0
6473 ** @@
6474 ******************************************************************************/
6475 
ensFeaturepairSetSourceFeature(EnsPFeaturepair fp,EnsPFeature feature)6476 AjBool ensFeaturepairSetSourceFeature(EnsPFeaturepair fp,
6477                                       EnsPFeature feature)
6478 {
6479     if (ajDebugTest("ensFeaturepairSetSourceFeature"))
6480     {
6481         ajDebug("ensFeaturepairSetSourceFeature\n"
6482                 "  fp %p\n"
6483                 "  feature %p\n",
6484                 fp,
6485                 feature);
6486 
6487         ensFeaturepairTrace(fp, 1);
6488 
6489         ensFeatureTrace(feature, 1);
6490     }
6491 
6492     if (!fp)
6493         return ajFalse;
6494 
6495     /* Replace the current Feature. */
6496 
6497     ensFeatureDel(&fp->SourceFeature);
6498 
6499     fp->SourceFeature = ensFeatureNewRef(feature);
6500 
6501     return ajTrue;
6502 }
6503 
6504 
6505 
6506 
6507 /* @func ensFeaturepairSetSourceSpecies ***************************************
6508 **
6509 ** Set the source species member of an Ensembl Feature Pair.
6510 **
6511 ** @cc Bio::EnsEMBL::FeaturePair::species
6512 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6513 ** @param [u] species [AjPStr] Source species
6514 **
6515 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6516 **
6517 ** @release 6.2.0
6518 ** @@
6519 ******************************************************************************/
6520 
ensFeaturepairSetSourceSpecies(EnsPFeaturepair fp,AjPStr species)6521 AjBool ensFeaturepairSetSourceSpecies(EnsPFeaturepair fp,
6522                                       AjPStr species)
6523 {
6524     if (!fp)
6525         return ajFalse;
6526 
6527     ajStrDel(&fp->SourceSpecies);
6528 
6529     if (species)
6530         fp->SourceSpecies = ajStrNewRef(species);
6531 
6532     return ajTrue;
6533 }
6534 
6535 
6536 
6537 
6538 /* @func ensFeaturepairSetTargetCoverage **************************************
6539 **
6540 ** Set the target coverage member of an Ensembl Feature Pair.
6541 **
6542 ** @cc Bio::EnsEMBL::FeaturePair::hcoverage
6543 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6544 ** @param [r] coverage [float] Target coverage
6545 **
6546 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6547 **
6548 ** @release 6.2.0
6549 ** @@
6550 ******************************************************************************/
6551 
ensFeaturepairSetTargetCoverage(EnsPFeaturepair fp,float coverage)6552 AjBool ensFeaturepairSetTargetCoverage(EnsPFeaturepair fp,
6553                                        float coverage)
6554 {
6555     if (!fp)
6556         return ajFalse;
6557 
6558     fp->TargetCoverage = coverage;
6559 
6560     return ajTrue;
6561 }
6562 
6563 
6564 
6565 
6566 /* @func ensFeaturepairSetTargetFeature ***************************************
6567 **
6568 ** Set the target Ensembl Feature member of an Ensembl Feature Pair.
6569 **
6570 ** @cc Bio::EnsEMBL::FeaturePair::hslice
6571 ** @cc Bio::EnsEMBL::FeaturePair::hseqname
6572 ** @cc Bio::EnsEMBL::FeaturePair::hstart
6573 ** @cc Bio::EnsEMBL::FeaturePair::hend
6574 ** @cc Bio::EnsEMBL::FeaturePair::hstrand
6575 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6576 ** @param [u] feature [EnsPFeature] Target Ensembl Feature
6577 **
6578 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6579 **
6580 ** @release 6.2.0
6581 ** @@
6582 ******************************************************************************/
6583 
ensFeaturepairSetTargetFeature(EnsPFeaturepair fp,EnsPFeature feature)6584 AjBool ensFeaturepairSetTargetFeature(EnsPFeaturepair fp,
6585                                       EnsPFeature feature)
6586 {
6587     if (ajDebugTest("ensFeaturepairSetTargetFeature"))
6588     {
6589         ajDebug("ensFeaturepairSetTargetFeature\n"
6590                 "  fp %p\n"
6591                 "  feature %p\n",
6592                 fp,
6593                 feature);
6594 
6595         ensFeaturepairTrace(fp, 1);
6596 
6597         ensFeatureTrace(feature, 1);
6598     }
6599 
6600     if (!fp)
6601         return ajFalse;
6602 
6603     /* Replace the current Feature. */
6604 
6605     ensFeatureDel(&fp->TargetFeature);
6606 
6607     fp->TargetFeature = ensFeatureNewRef(feature);
6608 
6609     return ajTrue;
6610 }
6611 
6612 
6613 
6614 
6615 /* @func ensFeaturepairSetTargetSpecies ***************************************
6616 **
6617 ** Set the target species member of an Ensembl Feature Pair.
6618 **
6619 ** @cc Bio::EnsEMBL::FeaturePair::hspecies
6620 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6621 ** @param [u] tspecies [AjPStr] Target species
6622 **
6623 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6624 **
6625 ** @release 6.2.0
6626 ** @@
6627 ******************************************************************************/
6628 
ensFeaturepairSetTargetSpecies(EnsPFeaturepair fp,AjPStr tspecies)6629 AjBool ensFeaturepairSetTargetSpecies(EnsPFeaturepair fp,
6630                                       AjPStr tspecies)
6631 {
6632     if (!fp)
6633         return ajFalse;
6634 
6635     ajStrDel(&fp->TargetSpecies);
6636 
6637     if (tspecies)
6638         fp->TargetSpecies = ajStrNewRef(tspecies);
6639 
6640     return ajTrue;
6641 }
6642 
6643 
6644 
6645 
6646 /* @section debugging *********************************************************
6647 **
6648 ** Functions for reporting of an Ensembl Feature Pair object.
6649 **
6650 ** @fdata [EnsPFeaturepair]
6651 **
6652 ** @nam3rule Trace Report Ensembl Feature Pair members to debug file
6653 **
6654 ** @argrule Trace fp [const EnsPFeaturepair] Ensembl Feature Pair
6655 ** @argrule Trace level [ajuint] Indentation level
6656 **
6657 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
6658 **
6659 ** @fcategory misc
6660 ******************************************************************************/
6661 
6662 
6663 
6664 
6665 /* @func ensFeaturepairTrace **************************************************
6666 **
6667 ** Trace an Ensembl Feature Pair.
6668 **
6669 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6670 ** @param [r] level [ajuint] Indentation level
6671 **
6672 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
6673 **
6674 ** @release 6.2.0
6675 ** @@
6676 ******************************************************************************/
6677 
ensFeaturepairTrace(const EnsPFeaturepair fp,ajuint level)6678 AjBool ensFeaturepairTrace(const EnsPFeaturepair fp, ajuint level)
6679 {
6680     AjPStr indent = NULL;
6681 
6682     if (!fp)
6683         return ajFalse;
6684 
6685     indent = ajStrNew();
6686 
6687     ajStrAppendCountK(&indent, ' ', level * 2);
6688 
6689     ajDebug("ensFeaturepairTrace %p\n"
6690             "%S  SourceFeature %p\n"
6691             "%S  TargetFeature %p\n"
6692             "%S  Externaldatabase %p\n"
6693             "%S  Extradata %p\n"
6694             "%S  SourceSpecies '%S'\n"
6695             "%S  TargetSpecies '%S'\n"
6696             "%S  Groupidentifier %d\n"
6697             "%S  Levelidentifier %d\n"
6698             "%S  Use %u\n"
6699             "%S  Evalue %f\n"
6700             "%S  Score %f\n"
6701             "%S  SourceCoverage %f\n"
6702             "%S  TargetCoverage %f\n"
6703             "%S  Identity %f\n",
6704             indent, fp,
6705             indent, fp->SourceFeature,
6706             indent, fp->TargetFeature,
6707             indent, fp->Externaldatabase,
6708             indent, fp->Extradata,
6709             indent, fp->SourceSpecies,
6710             indent, fp->TargetSpecies,
6711             indent, fp->Groupidentifier,
6712             indent, fp->Levelidentifier,
6713             indent, fp->Use,
6714             indent, fp->Evalue,
6715             indent, fp->Score,
6716             indent, fp->SourceCoverage,
6717             indent, fp->TargetCoverage,
6718             indent, fp->Identity);
6719 
6720     ensFeatureTrace(fp->SourceFeature, level + 1);
6721 
6722     ensFeatureTrace(fp->TargetFeature, level + 1);
6723 
6724     ensExternaldatabaseTrace(fp->Externaldatabase, level + 1);
6725 
6726     ajStrDel(&indent);
6727 
6728     return ajTrue;
6729 }
6730 
6731 
6732 
6733 
6734 /* @section calculate *********************************************************
6735 **
6736 ** Functions for calculating information from an Ensembl Feature Pair object.
6737 **
6738 ** @fdata [EnsPFeaturepair]
6739 **
6740 ** @nam3rule Calculate Calculate Ensembl Feature Pair information
6741 ** @nam4rule Memsize Calculate the memory size in bytes
6742 **
6743 ** @argrule * fp [const EnsPFeaturepair] Ensembl Feature Pair
6744 **
6745 ** @valrule Memsize [size_t] Memory size in bytes or 0
6746 **
6747 ** @fcategory misc
6748 ******************************************************************************/
6749 
6750 
6751 
6752 
6753 /* @func ensFeaturepairCalculateMemsize ***************************************
6754 **
6755 ** Calculate the memory size in bytes of an Ensembl Feature Pair.
6756 **
6757 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6758 **
6759 ** @return [size_t] Memory size in bytes or 0
6760 **
6761 ** @release 6.4.0
6762 ** @@
6763 ******************************************************************************/
6764 
ensFeaturepairCalculateMemsize(const EnsPFeaturepair fp)6765 size_t ensFeaturepairCalculateMemsize(const EnsPFeaturepair fp)
6766 {
6767     size_t size = 0;
6768 
6769     if (!fp)
6770         return 0;
6771 
6772     size += sizeof (EnsOFeaturepair);
6773 
6774     size += ensFeatureCalculateMemsize(fp->SourceFeature);
6775     size += ensFeatureCalculateMemsize(fp->TargetFeature);
6776 
6777     if (fp->Extradata)
6778     {
6779         size += sizeof (AjOStr);
6780 
6781         size += ajStrGetRes(fp->Extradata);
6782     }
6783 
6784     if (fp->SourceSpecies)
6785     {
6786         size += sizeof (AjOStr);
6787 
6788         size += ajStrGetRes(fp->SourceSpecies);
6789     }
6790 
6791     if (fp->TargetSpecies)
6792     {
6793         size += sizeof (AjOStr);
6794 
6795         size += ajStrGetRes(fp->TargetSpecies);
6796     }
6797 
6798     return size;
6799 }
6800 
6801 
6802 
6803 
6804 /* @section map ***************************************************************
6805 **
6806 ** Functions for mapping Ensembl Feature Pair objects between
6807 ** Ensembl Coordinate System objects.
6808 **
6809 ** @fdata [EnsPFeaturepair]
6810 **
6811 ** @nam3rule Transfer Transfer an Ensembl Feature Pair
6812 ** @nam3rule Transform Transform an Ensembl Feature Pair
6813 **
6814 ** @argrule Transfer fp [EnsPFeaturepair] Ensembl Feature Pair
6815 ** @argrule Transfer slice [EnsPSlice] Ensembl Slice
6816 ** @argrule Transform fp [const EnsPFeaturepair] Ensembl Feature Pair
6817 ** @argrule Transform csname [const AjPStr] Ensembl Coordinate System name
6818 ** @argrule Transform csversion [const AjPStr] Ensembl Coordinate System
6819 **                                             version
6820 **
6821 ** @valrule * [EnsPFeaturepair] Ensembl Feature Pair or NULL
6822 **
6823 ** @fcategory misc
6824 ******************************************************************************/
6825 
6826 
6827 
6828 
6829 /* @func ensFeaturepairTransfer ***********************************************
6830 **
6831 ** Transfer an Ensembl Feature Pair onto another Ensembl Slice.
6832 **
6833 ** @cc Bio::EnsEMBL::Feature::transfer
6834 ** @param [u] fp [EnsPFeaturepair] Ensembl Feature Pair
6835 ** @param [u] slice [EnsPSlice] Ensembl Slice
6836 ** @see ensFeatureTransfer
6837 **
6838 ** @return [EnsPFeaturepair] Ensembl Feature Pair or NULL
6839 **
6840 ** @release 6.2.0
6841 ** @@
6842 ******************************************************************************/
6843 
ensFeaturepairTransfer(EnsPFeaturepair fp,EnsPSlice slice)6844 EnsPFeaturepair ensFeaturepairTransfer(EnsPFeaturepair fp,
6845                                        EnsPSlice slice)
6846 {
6847     EnsPFeature newfeature = NULL;
6848     EnsPFeaturepair newfp  = NULL;
6849 
6850     if (!fp)
6851         return NULL;
6852 
6853     if (!slice)
6854         return NULL;
6855 
6856     newfeature = ensFeatureTransfer(fp->SourceFeature, slice);
6857 
6858     if (!newfeature)
6859         return NULL;
6860 
6861     newfp = ensFeaturepairNewCpy(fp);
6862 
6863     ensFeaturepairSetSourceFeature(newfp, newfeature);
6864 
6865     ensFeatureDel(&newfeature);
6866 
6867     return newfp;
6868 }
6869 
6870 
6871 
6872 
6873 /* @func ensFeaturepairTransform **********************************************
6874 **
6875 ** Transform an Ensembl Feature Pair into another Ensembl Coordinate System.
6876 **
6877 ** @cc Bio::EnsEMBL::Feature::transform
6878 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6879 ** @param [r] csname [const AjPStr] Ensembl Coordinate System name
6880 ** @param [r] csversion [const AjPStr] Ensembl Coordinate System version
6881 ** @see ensFeatureTransform
6882 **
6883 ** @return [EnsPFeaturepair] Ensembl Feature Pair or NULL
6884 **
6885 ** @release 6.2.0
6886 ** @@
6887 ******************************************************************************/
6888 
ensFeaturepairTransform(const EnsPFeaturepair fp,const AjPStr csname,const AjPStr csversion)6889 EnsPFeaturepair ensFeaturepairTransform(const EnsPFeaturepair fp,
6890                                         const AjPStr csname,
6891                                         const AjPStr csversion)
6892 {
6893     EnsPFeature nfeature = NULL;
6894     EnsPFeaturepair nfp  = NULL;
6895 
6896     if (!fp)
6897         return NULL;
6898 
6899     if (!csname)
6900         return NULL;
6901 
6902     if (!csversion)
6903         return NULL;
6904 
6905     nfeature = ensFeatureTransform(fp->SourceFeature,
6906                                    csname,
6907                                    csversion,
6908                                    (EnsPSlice) NULL);
6909 
6910     if (!nfeature)
6911         return NULL;
6912 
6913     nfp = ensFeaturepairNewCpy(fp);
6914 
6915     ensFeaturepairSetSourceFeature(nfp, nfeature);
6916 
6917     ensFeatureDel(&nfeature);
6918 
6919     return nfp;
6920 }
6921 
6922 
6923 
6924 
6925 /* @section convenience functions *********************************************
6926 **
6927 ** Ensembl Feature Pair convenience functions
6928 **
6929 ** @fdata [EnsPFeaturepair]
6930 **
6931 ** @nam3rule Get Get member(s) of associated objects
6932 ** @nam4rule Source Get Ensembl Feature member(s) for the source
6933 ** @nam4rule Target Get Ensembl Feature member(s) for the target
6934 ** @nam5rule End Get the Ensembl Feature end
6935 ** @nam5rule Start Get the Ensembl Feature start
6936 ** @nam5rule Strand Get the Ensembl Feature strand
6937 **
6938 ** @argrule * fp [const EnsPFeaturepair] Ensembl Feature Pair
6939 **
6940 ** @valrule End [ajint] Ensembl Feature end or 0
6941 ** @valrule Start [ajint] Ensembl Feature start or 0
6942 ** @valrule Strand [ajint] Ensembl Feature strand or 0
6943 **
6944 ** @fcategory use
6945 ******************************************************************************/
6946 
6947 
6948 
6949 
6950 /* @func ensFeaturepairGetSourceEnd *******************************************
6951 **
6952 ** Get the end member of the
6953 ** source Ensembl Feature member of an Ensembl Feature Pair.
6954 **
6955 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6956 **
6957 ** @return [ajint] Ensembl Feature end or 0
6958 ** @@
6959 ******************************************************************************/
6960 
ensFeaturepairGetSourceEnd(const EnsPFeaturepair fp)6961 ajint ensFeaturepairGetSourceEnd(const EnsPFeaturepair fp)
6962 {
6963     return (fp && fp->SourceFeature) ?
6964         ensFeatureGetEnd(fp->SourceFeature) : 0;
6965 }
6966 
6967 
6968 
6969 
6970 /* @func ensFeaturepairGetSourceStart *****************************************
6971 **
6972 ** Get the start member of the
6973 ** source Ensembl Feature member of an Ensembl Feature Pair.
6974 **
6975 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6976 **
6977 ** @return [ajint] Ensembl Feature start or 0
6978 ** @@
6979 ******************************************************************************/
6980 
ensFeaturepairGetSourceStart(const EnsPFeaturepair fp)6981 ajint ensFeaturepairGetSourceStart(const EnsPFeaturepair fp)
6982 {
6983     return (fp && fp->SourceFeature) ?
6984         ensFeatureGetStart(fp->SourceFeature) : 0;
6985 }
6986 
6987 
6988 
6989 
6990 /* @func ensFeaturepairGetSourceStrand ****************************************
6991 **
6992 ** Get the strand member of the
6993 ** source Ensembl Feature member of an Ensembl Feature Pair.
6994 **
6995 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
6996 **
6997 ** @return [ajint] Ensembl Feature strand or 0
6998 ** @@
6999 ******************************************************************************/
7000 
ensFeaturepairGetSourceStrand(const EnsPFeaturepair fp)7001 ajint ensFeaturepairGetSourceStrand(const EnsPFeaturepair fp)
7002 {
7003     return (fp && fp->SourceFeature) ?
7004         ensFeatureGetStrand(fp->SourceFeature) : 0;
7005 }
7006 
7007 
7008 
7009 
7010 /* @func ensFeaturepairGetTargetEnd *******************************************
7011 **
7012 ** Get the end member of the
7013 ** target Ensembl Feature member of an Ensembl Feature Pair.
7014 **
7015 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
7016 **
7017 ** @return [ajint] Ensembl Feature end or 0
7018 ** @@
7019 ******************************************************************************/
7020 
ensFeaturepairGetTargetEnd(const EnsPFeaturepair fp)7021 ajint ensFeaturepairGetTargetEnd(const EnsPFeaturepair fp)
7022 {
7023     return (fp && fp->TargetFeature) ?
7024         ensFeatureGetEnd(fp->TargetFeature) : 0;
7025 }
7026 
7027 
7028 
7029 
7030 /* @func ensFeaturepairGetTargetStart *****************************************
7031 **
7032 ** Get the start member of the
7033 ** target Ensembl Feature member of an Ensembl Feature Pair.
7034 **
7035 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
7036 **
7037 ** @return [ajint] Ensembl Feature start or 0
7038 ** @@
7039 ******************************************************************************/
7040 
ensFeaturepairGetTargetStart(const EnsPFeaturepair fp)7041 ajint ensFeaturepairGetTargetStart(const EnsPFeaturepair fp)
7042 {
7043     return (fp && fp->TargetFeature) ?
7044         ensFeatureGetStart(fp->TargetFeature) : 0;
7045 }
7046 
7047 
7048 
7049 
7050 /* @func ensFeaturepairGetTargetStrand ****************************************
7051 **
7052 ** Get the strand member of the
7053 ** target Ensembl Feature member of an Ensembl Feature Pair.
7054 **
7055 ** @param [r] fp [const EnsPFeaturepair] Ensembl Feature Pair
7056 **
7057 ** @return [ajint] Ensembl Feature strand or 0
7058 ** @@
7059 ******************************************************************************/
7060 
ensFeaturepairGetTargetStrand(const EnsPFeaturepair fp)7061 ajint ensFeaturepairGetTargetStrand(const EnsPFeaturepair fp)
7062 {
7063     return (fp && fp->TargetFeature) ?
7064         ensFeatureGetStrand(fp->TargetFeature) : 0;
7065 }
7066 
7067 
7068 
7069 
7070 /* @section comparing *********************************************************
7071 **
7072 ** Functions for comparing Ensembl Feature Pair objects
7073 **
7074 ** @fdata [EnsPFeaturepair]
7075 **
7076 ** @nam3rule Compare Compare two Ensembl Feature Pair objects
7077 ** @nam4rule Source  Compare by source Ensembl Feature object members
7078 ** @nam4rule Target  Compare by target Ensembl Feature object members
7079 ** @nam5rule End     Compare by Ensembl Feature end members
7080 ** @nam5rule Start   Compare by Ensembl Feature start members
7081 ** @nam6rule Ascending  Compare in ascending order
7082 ** @nam6rule Descending Compare in descending order
7083 **
7084 ** @argrule * fp1 [const EnsPFeaturepair] Ensembl Feature Pair 1
7085 ** @argrule * fp2 [const EnsPFeaturepair] Ensembl Feature Pair 2
7086 **
7087 ** @valrule * [int] The comparison function returns an integer less than,
7088 **                  equal to, or greater than zero if the first argument is
7089 **                  considered to be respectively less than, equal to, or
7090 **                  greater than the second.
7091 **
7092 ** @fcategory use
7093 ******************************************************************************/
7094 
7095 
7096 
7097 
7098 /* @func ensFeaturepairCompareSourceEndAscending ******************************
7099 **
7100 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7101 ** Source Ensembl Feature end member in ascending order.
7102 **
7103 ** Ensembl Feature Pair objects without a source Ensembl Feature sort
7104 ** towards the end of the AJAX List.
7105 **
7106 ** @param [r] fp1 [const EnsPFeaturepair] Ensembl Feature Pair 1
7107 ** @param [r] fp2 [const EnsPFeaturepair] Ensembl Feature Pair 2
7108 ** @see ajListSort
7109 **
7110 ** @return [int] The comparison function returns an integer less than,
7111 **               equal to, or greater than zero if the first argument is
7112 **               considered to be respectively less than, equal to, or
7113 **               greater than the second.
7114 **
7115 ** @release 6.4.0
7116 ** @@
7117 ******************************************************************************/
7118 
ensFeaturepairCompareSourceEndAscending(const EnsPFeaturepair fp1,const EnsPFeaturepair fp2)7119 int ensFeaturepairCompareSourceEndAscending(const EnsPFeaturepair fp1,
7120                                             const EnsPFeaturepair fp2)
7121 {
7122     if (ajDebugTest("ensFeaturepairCompareSourceEndAscending"))
7123     {
7124         ajDebug("ensFeaturepairCompareSourceEndAscending\n"
7125                 "  fp1 %p\n"
7126                 "  fp2 %p\n",
7127                 fp1,
7128                 fp2);
7129 
7130         ensFeaturepairTrace(fp1, 1);
7131         ensFeaturepairTrace(fp2, 1);
7132     }
7133 
7134     /* Sort empty values towards the end of the AJAX List. */
7135 
7136     if (fp1 && (!fp2))
7137         return -1;
7138 
7139     if ((!fp1) && (!fp2))
7140         return 0;
7141 
7142     if ((!fp1) && fp2)
7143         return +1;
7144 
7145     return ensFeatureCompareEndAscending(fp1->SourceFeature,
7146                                          fp2->SourceFeature);
7147 }
7148 
7149 
7150 
7151 
7152 /* @func ensFeaturepairCompareSourceEndDescending *****************************
7153 **
7154 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7155 ** source Ensembl Feature end member in descending order.
7156 **
7157 ** Ensembl Feature Pair objects without a source Ensembl Feature sort
7158 ** towards the end of the AJAX List.
7159 **
7160 ** @param [r] fp1 [const EnsPFeaturepair] Ensembl Feature Pair 1
7161 ** @param [r] fp2 [const EnsPFeaturepair] Ensembl Feature Pair 2
7162 ** @see ajListSort
7163 **
7164 ** @return [int] The comparison function returns an integer less than,
7165 **               equal to, or greater than zero if the first argument is
7166 **               considered to be respectively less than, equal to, or
7167 **               greater than the second.
7168 **
7169 ** @release 6.4.0
7170 ** @@
7171 ******************************************************************************/
7172 
ensFeaturepairCompareSourceEndDescending(const EnsPFeaturepair fp1,const EnsPFeaturepair fp2)7173 int ensFeaturepairCompareSourceEndDescending(const EnsPFeaturepair fp1,
7174                                              const EnsPFeaturepair fp2)
7175 {
7176     if (ajDebugTest("ensFeaturepairCompareSourceEndDescending"))
7177     {
7178         ajDebug("ensFeaturepairCompareSourceEndDescending\n"
7179                 "  fp1 %p\n"
7180                 "  fp2 %p\n",
7181                 fp1,
7182                 fp2);
7183 
7184         ensFeaturepairTrace(fp1, 1);
7185         ensFeaturepairTrace(fp2, 1);
7186     }
7187 
7188     /* Sort empty values towards the end of the AJAX List. */
7189 
7190     if (fp1 && (!fp2))
7191         return -1;
7192 
7193     if ((!fp1) && (!fp2))
7194         return 0;
7195 
7196     if ((!fp1) && fp2)
7197         return +1;
7198 
7199     return ensFeatureCompareEndDescending(fp1->SourceFeature,
7200                                           fp2->SourceFeature);
7201 }
7202 
7203 
7204 
7205 
7206 /* @func ensFeaturepairCompareSourceStartAscending ****************************
7207 **
7208 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7209 ** Source Ensembl Feature start member in ascending order.
7210 **
7211 ** Ensembl Feature Pair objects without a source Ensembl Feature sort
7212 ** towards the end of the AJAX List.
7213 **
7214 ** @param [r] fp1 [const EnsPFeaturepair] Ensembl Feature Pair 1
7215 ** @param [r] fp2 [const EnsPFeaturepair] Ensembl Feature Pair 2
7216 ** @see ajListSort
7217 **
7218 ** @return [int] The comparison function returns an integer less than,
7219 **               equal to, or greater than zero if the first argument is
7220 **               considered to be respectively less than, equal to, or
7221 **               greater than the second.
7222 **
7223 ** @release 6.4.0
7224 ** @@
7225 ******************************************************************************/
7226 
ensFeaturepairCompareSourceStartAscending(const EnsPFeaturepair fp1,const EnsPFeaturepair fp2)7227 int ensFeaturepairCompareSourceStartAscending(const EnsPFeaturepair fp1,
7228                                               const EnsPFeaturepair fp2)
7229 {
7230     if (ajDebugTest("ensFeaturepairCompareSourceStartAscending"))
7231     {
7232         ajDebug("ensFeaturepairCompareSourceStartAscending\n"
7233                 "  fp1 %p\n"
7234                 "  fp2 %p\n",
7235                 fp1,
7236                 fp2);
7237 
7238         ensFeaturepairTrace(fp1, 1);
7239         ensFeaturepairTrace(fp2, 1);
7240     }
7241 
7242     /* Sort empty values towards the end of the AJAX List. */
7243 
7244     if (fp1 && (!fp2))
7245         return -1;
7246 
7247     if ((!fp1) && (!fp2))
7248         return 0;
7249 
7250     if ((!fp1) && fp2)
7251         return +1;
7252 
7253     return ensFeatureCompareStartAscending(fp1->SourceFeature,
7254                                            fp2->SourceFeature);
7255 }
7256 
7257 
7258 
7259 
7260 /* @func ensFeaturepairCompareSourceStartDescending ***************************
7261 **
7262 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7263 ** source Ensembl Feature start member in descending order.
7264 **
7265 ** Ensembl Feature Pair objects without a source Ensembl Feature sort
7266 ** towards the end of the AJAX List.
7267 **
7268 ** @param [r] fp1 [const EnsPFeaturepair] Ensembl Feature Pair 1
7269 ** @param [r] fp2 [const EnsPFeaturepair] Ensembl Feature Pair 2
7270 ** @see ajListSort
7271 **
7272 ** @return [int] The comparison function returns an integer less than,
7273 **               equal to, or greater than zero if the first argument is
7274 **               considered to be respectively less than, equal to, or
7275 **               greater than the second.
7276 **
7277 ** @release 6.4.0
7278 ** @@
7279 ******************************************************************************/
7280 
ensFeaturepairCompareSourceStartDescending(const EnsPFeaturepair fp1,const EnsPFeaturepair fp2)7281 int ensFeaturepairCompareSourceStartDescending(const EnsPFeaturepair fp1,
7282                                                const EnsPFeaturepair fp2)
7283 {
7284     if (ajDebugTest("ensFeaturepairCompareSourceStartDescending"))
7285     {
7286         ajDebug("ensFeaturepairCompareSourceStartDescending\n"
7287                 "  fp1 %p\n"
7288                 "  fp2 %p\n",
7289                 fp1,
7290                 fp2);
7291 
7292         ensFeaturepairTrace(fp1, 1);
7293         ensFeaturepairTrace(fp2, 1);
7294     }
7295 
7296     /* Sort empty values towards the end of the AJAX List. */
7297 
7298     if (fp1 && (!fp2))
7299         return -1;
7300 
7301     if ((!fp1) && (!fp2))
7302         return 0;
7303 
7304     if ((!fp1) && fp2)
7305         return +1;
7306 
7307     return ensFeatureCompareStartDescending(fp1->SourceFeature,
7308                                             fp2->SourceFeature);
7309 }
7310 
7311 
7312 
7313 
7314 /* @datasection [AjPList] AJAX List *******************************************
7315 **
7316 ** @nam2rule List Functions for manipulating AJAX List objects
7317 **
7318 ******************************************************************************/
7319 
7320 
7321 
7322 
7323 /* @funcstatic listFeaturepairCompareSourceEndAscending ***********************
7324 **
7325 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7326 ** source Ensembl Feature end member in ascending order.
7327 **
7328 ** Ensembl Feature Pair objects without a source Ensembl Feature object sort
7329 ** towards the end of the AJAX List.
7330 **
7331 ** @param [r] item1 [const void*] Ensembl Feature Pair address 1
7332 ** @param [r] item2 [const void*] Ensembl Feature Pair address 2
7333 ** @see ajListSort
7334 **
7335 ** @return [int] The comparison function returns an integer less than,
7336 **               equal to, or greater than zero if the first argument is
7337 **               considered to be respectively less than, equal to, or
7338 **               greater than the second.
7339 **
7340 ** @release 6.4.0
7341 ** @@
7342 ******************************************************************************/
7343 
listFeaturepairCompareSourceEndAscending(const void * item1,const void * item2)7344 static int listFeaturepairCompareSourceEndAscending(
7345     const void *item1,
7346     const void *item2)
7347 {
7348     EnsPFeaturepair fp1 = *(EnsOFeaturepair *const *) item1;
7349     EnsPFeaturepair fp2 = *(EnsOFeaturepair *const *) item2;
7350 
7351 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
7352     if (ajDebugTest("ensFeaturepairCompareSourceEndAscending"))
7353     {
7354         ajDebug("ensFeaturepairCompareSourceEndAscending\n"
7355                 "  fp1 %p\n"
7356                 "  fp2 %p\n",
7357                 fp1,
7358                 fp2);
7359 
7360         ensFeaturepairTrace(fp1, 1);
7361         ensFeaturepairTrace(fp2, 1);
7362     }
7363 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
7364 
7365     /* Sort empty values towards the end of the AJAX List. */
7366 
7367     if (fp1 && (!fp2))
7368         return -1;
7369 
7370     if ((!fp1) && (!fp2))
7371         return 0;
7372 
7373     if ((!fp1) && fp2)
7374         return +1;
7375 
7376     return ensFeaturepairCompareSourceEndAscending(fp1, fp2);
7377 }
7378 
7379 
7380 
7381 
7382 /* @funcstatic listFeaturepairCompareSourceEndDescending **********************
7383 **
7384 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7385 ** source Ensembl Feature end member in descending order.
7386 **
7387 ** Ensembl Feature Pair objects without a source Ensembl Feature object sort
7388 ** towards the end of the AJAX List.
7389 **
7390 ** @param [r] item1 [const void*] Ensembl Feature Pair address 1
7391 ** @param [r] item2 [const void*] Ensembl Feature Pair address 2
7392 ** @see ajListSort
7393 **
7394 ** @return [int] The comparison function returns an integer less than,
7395 **               equal to, or greater than zero if the first argument is
7396 **               considered to be respectively less than, equal to, or
7397 **               greater than the second.
7398 **
7399 ** @release 6.4.0
7400 ** @@
7401 ******************************************************************************/
7402 
listFeaturepairCompareSourceEndDescending(const void * item1,const void * item2)7403 static int listFeaturepairCompareSourceEndDescending(
7404     const void *item1,
7405     const void *item2)
7406 {
7407     EnsPFeaturepair fp1 = *(EnsOFeaturepair *const *) item1;
7408     EnsPFeaturepair fp2 = *(EnsOFeaturepair *const *) item2;
7409 
7410 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
7411     if (ajDebugTest("ensFeaturepairCompareSourceEndDescending"))
7412     {
7413         ajDebug("ensFeaturepairCompareSourceEndDescending\n"
7414                 "  fp1 %p\n"
7415                 "  fp2 %p\n",
7416                 fp1,
7417                 fp2);
7418 
7419         ensFeaturepairTrace(fp1, 1);
7420         ensFeaturepairTrace(fp2, 1);
7421     }
7422 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
7423 
7424     /* Sort empty values towards the end of the AJAX List. */
7425 
7426     if (fp1 && (!fp2))
7427         return -1;
7428 
7429     if ((!fp1) && (!fp2))
7430         return 0;
7431 
7432     if ((!fp1) && fp2)
7433         return +1;
7434 
7435     return ensFeaturepairCompareSourceEndDescending(fp1, fp2);
7436 }
7437 
7438 
7439 
7440 
7441 /* @funcstatic listFeaturepairCompareSourceStartAscending *********************
7442 **
7443 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7444 ** source Ensembl Feature start member in ascending order.
7445 **
7446 ** Ensembl Feature Pair objects without a source Ensembl Feature object sort
7447 ** towards the end of the AJAX List.
7448 **
7449 ** @param [r] item1 [const void*] Ensembl Feature Pair address 1
7450 ** @param [r] item2 [const void*] Ensembl Feature Pair address 2
7451 ** @see ajListSort
7452 **
7453 ** @return [int] The comparison function returns an integer less than,
7454 **               equal to, or greater than zero if the first argument is
7455 **               considered to be respectively less than, equal to, or
7456 **               greater than the second.
7457 **
7458 ** @release 6.4.0
7459 ** @@
7460 ******************************************************************************/
7461 
listFeaturepairCompareSourceStartAscending(const void * item1,const void * item2)7462 static int listFeaturepairCompareSourceStartAscending(
7463     const void *item1,
7464     const void *item2)
7465 {
7466     EnsPFeaturepair fp1 = *(EnsOFeaturepair *const *) item1;
7467     EnsPFeaturepair fp2 = *(EnsOFeaturepair *const *) item2;
7468 
7469 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
7470     if (ajDebugTest("ensFeaturepairCompareSourceStartAscending"))
7471     {
7472         ajDebug("ensFeaturepairCompareSourceStartAscending\n"
7473                 "  fp1 %p\n"
7474                 "  fp2 %p\n",
7475                 fp1,
7476                 fp2);
7477 
7478         ensFeaturepairTrace(fp1, 1);
7479         ensFeaturepairTrace(fp2, 1);
7480     }
7481 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
7482 
7483     /* Sort empty values towards the end of the AJAX List. */
7484 
7485     if (fp1 && (!fp2))
7486         return -1;
7487 
7488     if ((!fp1) && (!fp2))
7489         return 0;
7490 
7491     if ((!fp1) && fp2)
7492         return +1;
7493 
7494     return ensFeaturepairCompareSourceStartAscending(fp1, fp2);
7495 }
7496 
7497 
7498 
7499 
7500 /* @funcstatic listFeaturepairCompareSourceStartDescending ********************
7501 **
7502 ** AJAX List of Ensembl Feature Pair objects comparison function to sort by
7503 ** source Ensembl Feature start member in descending order.
7504 **
7505 ** Ensembl Feature Pair objects without a source Ensembl Feature object sort
7506 ** towards the end of the AJAX List.
7507 **
7508 ** @param [r] item1 [const void*] Ensembl Feature Pair address 1
7509 ** @param [r] item2 [const void*] Ensembl Feature Pair address 2
7510 ** @see ajListSort
7511 **
7512 ** @return [int] The comparison function returns an integer less than,
7513 **               equal to, or greater than zero if the first argument is
7514 **               considered to be respectively less than, equal to, or
7515 **               greater than the second.
7516 **
7517 ** @release 6.4.0
7518 ** @@
7519 ******************************************************************************/
7520 
listFeaturepairCompareSourceStartDescending(const void * item1,const void * item2)7521 static int listFeaturepairCompareSourceStartDescending(
7522     const void *item1,
7523     const void *item2)
7524 {
7525     EnsPFeaturepair fp1 = *(EnsOFeaturepair *const *) item1;
7526     EnsPFeaturepair fp2 = *(EnsOFeaturepair *const *) item2;
7527 
7528 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
7529     if (ajDebugTest("ensFeaturepairCompareSourceStartDescending"))
7530     {
7531         ajDebug("ensFeaturepairCompareSourceStartDescending\n"
7532                 "  fp1 %p\n"
7533                 "  fp2 %p\n",
7534                 fp1,
7535                 fp2);
7536 
7537         ensFeaturepairTrace(fp1, 1);
7538         ensFeaturepairTrace(fp2, 1);
7539     }
7540 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
7541 
7542     /* Sort empty values towards the end of the AJAX List. */
7543 
7544     if (fp1 && (!fp2))
7545         return -1;
7546 
7547     if ((!fp1) && (!fp2))
7548         return 0;
7549 
7550     if ((!fp1) && fp2)
7551         return +1;
7552 
7553     return ensFeaturepairCompareSourceStartDescending(fp1, fp2);
7554 }
7555 
7556 
7557 
7558 
7559 /* @section list **************************************************************
7560 **
7561 ** Functions for manipulating AJAX List objects.
7562 **
7563 ** @fdata [AjPList]
7564 **
7565 ** @nam3rule Featurepair Functions for manipulating AJAX List objects of
7566 ** Ensembl Feature Pair objects
7567 ** @nam4rule Sort       Sort functions
7568 ** @nam5rule Source     Sort by source Ensembl Feature member
7569 ** @nam5rule Target     Sort by target Ensembl Feature member
7570 ** @nam6rule End        Sort by Ensembl Feature end member
7571 ** @nam6rule Start      Sort by Ensembl Feature start member
7572 ** @nam7rule Ascending  Sort in ascending order
7573 ** @nam7rule Descending Sort in descending order
7574 **
7575 ** @argrule * fps [AjPList]  AJAX List of Ensembl Feature Pair objects
7576 **
7577 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
7578 **
7579 ** @fcategory misc
7580 ******************************************************************************/
7581 
7582 
7583 
7584 
7585 /* @func ensListFeaturepairSortSourceEndAscending *****************************
7586 **
7587 ** Sort an AJAX List of Ensembl Feature Pair objects by their source
7588 ** Ensembl Feature end coordinate in ascending order.
7589 **
7590 ** @param [u] fps [AjPList] AJAX List of Ensembl Feature Pair objects
7591 ** @see ensFeaturepairCompareSourceEndAscending
7592 **
7593 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
7594 **
7595 ** @release 6.4.0
7596 ** @@
7597 ******************************************************************************/
7598 
ensListFeaturepairSortSourceEndAscending(AjPList fps)7599 AjBool ensListFeaturepairSortSourceEndAscending(AjPList fps)
7600 {
7601     if (!fps)
7602         return ajFalse;
7603 
7604     ajListSortTwo(fps,
7605                   &listFeaturepairCompareSourceEndAscending,
7606                   &listFeaturepairCompareSourceStartAscending);
7607 
7608     return ajTrue;
7609 }
7610 
7611 
7612 
7613 
7614 /* @func ensListFeaturepairSortSourceEndDescending ****************************
7615 **
7616 ** Sort an AJAX List of Ensembl Feature Pair objects by their
7617 ** source Ensembl Feature end coordinate in descending order.
7618 **
7619 ** @param [u] fps [AjPList] AJAX List of Ensembl Feature Pair objects
7620 ** @see ensFeaturepairCompareSourceEndDescending
7621 **
7622 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
7623 **
7624 ** @release 6.4.0
7625 ** @@
7626 ******************************************************************************/
7627 
ensListFeaturepairSortSourceEndDescending(AjPList fps)7628 AjBool ensListFeaturepairSortSourceEndDescending(AjPList fps)
7629 {
7630     if (!fps)
7631         return ajFalse;
7632 
7633     ajListSortTwo(fps,
7634                   &listFeaturepairCompareSourceEndDescending,
7635                   &listFeaturepairCompareSourceStartDescending);
7636 
7637     return ajTrue;
7638 }
7639 
7640 
7641 
7642 
7643 /* @func ensListFeaturepairSortSourceStartAscending ***************************
7644 **
7645 ** Sort an AJAX List of Ensembl Feature Pair objects by their source
7646 ** Ensembl Feature start coordinate in ascending order.
7647 **
7648 ** @param [u] fps [AjPList] AJAX List of Ensembl Feature Pair objects
7649 ** @see ensFeaturepairCompareSourceStartAscending
7650 **
7651 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
7652 **
7653 ** @release 6.4.0
7654 ** @@
7655 ******************************************************************************/
7656 
ensListFeaturepairSortSourceStartAscending(AjPList fps)7657 AjBool ensListFeaturepairSortSourceStartAscending(AjPList fps)
7658 {
7659     if (!fps)
7660         return ajFalse;
7661 
7662     ajListSortTwo(fps,
7663                   &listFeaturepairCompareSourceStartAscending,
7664                   &listFeaturepairCompareSourceEndAscending);
7665 
7666     return ajTrue;
7667 }
7668 
7669 
7670 
7671 
7672 /* @func ensListFeaturepairSortSourceStartDescending **************************
7673 **
7674 ** Sort an AJAX List of Ensembl Feature Pair objects by their
7675 ** source Ensembl Feature start coordinate in descending order.
7676 **
7677 ** @param [u] fps [AjPList] AJAX List of Ensembl Feature Pair objects
7678 ** @see ensFeaturepairCompareSourceStartDescending
7679 **
7680 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
7681 **
7682 ** @release 6.4.0
7683 ** @@
7684 ******************************************************************************/
7685 
ensListFeaturepairSortSourceStartDescending(AjPList fps)7686 AjBool ensListFeaturepairSortSourceStartDescending(AjPList fps)
7687 {
7688     if (!fps)
7689         return ajFalse;
7690 
7691     ajListSortTwo(fps,
7692                   &listFeaturepairCompareSourceStartDescending,
7693                   &listFeaturepairCompareSourceEndDescending);
7694 
7695     return ajTrue;
7696 }
7697 
7698 
7699 
7700 
7701 /* @datasection [EnsPAssemblyexceptionfeature] Ensembl Assembly Exception
7702 ** Feature
7703 **
7704 ** @nam2rule Assemblyexceptionfeature Functions for manipulating
7705 ** Ensembl Assembly Exception Feature objects
7706 **
7707 ** @cc Bio::EnsEMBL::AssemblyExceptionFeature
7708 ** @cc CVS Revision: 1.9
7709 ** @cc CVS Tag: branch-ensembl-68
7710 **
7711 ******************************************************************************/
7712 
7713 
7714 
7715 
7716 /* @section constructors ******************************************************
7717 **
7718 ** All constructors return a new Ensembl Assembly Exception Feature by pointer.
7719 ** It is the responsibility of the user to first destroy any previous
7720 ** Assembly Exception Feature. The target pointer does not need to be
7721 ** initialised to NULL, but it is good programming practice to do so anyway.
7722 **
7723 ** @fdata [EnsPAssemblyexceptionfeature]
7724 **
7725 ** @nam3rule New Constructor
7726 ** @nam4rule Cpy Constructor with existing object
7727 ** @nam4rule Ini Constructor with initial values
7728 ** @nam4rule Ref Constructor by incrementing the reference counter
7729 **
7730 ** @argrule Cpy aef [const EnsPAssemblyexceptionfeature]
7731 ** Ensembl Assembly Exception Feature
7732 ** @argrule Ini aefa [EnsPAssemblyexceptionfeatureadaptor]
7733 ** Ensembl Assembly Exception Feature Adaptor
7734 ** @argrule Ini identifier [ajuint] SQL database-internal identifier
7735 ** @argrule Ini feature [EnsPFeature] Ensembl Feature
7736 ** @argrule Ini slice [EnsPSlice] Exception Ensembl Slice
7737 ** @argrule Ini type [EnsEAssemblyexceptionType]
7738 ** Ensembl Assembly Exception Type enumeration
7739 ** @argrule Ref aef [EnsPAssemblyexceptionfeature]
7740 ** Ensembl Assembly Exception Feature
7741 **
7742 ** @valrule * [EnsPAssemblyexceptionfeature]
7743 ** Ensembl Assembly Exception Feature or NULL
7744 **
7745 ** @fcategory new
7746 ******************************************************************************/
7747 
7748 
7749 
7750 
7751 /* @func ensAssemblyexceptionfeatureNewCpy ************************************
7752 **
7753 ** Object-based constructor function, which returns an independent object.
7754 **
7755 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
7756 ** Ensembl Assembly Exception Feature
7757 **
7758 ** @return [EnsPAssemblyexceptionfeature]
7759 ** Ensembl Assembly Exception Feature or NULL
7760 **
7761 ** @release 6.4.0
7762 ** @@
7763 ******************************************************************************/
7764 
ensAssemblyexceptionfeatureNewCpy(const EnsPAssemblyexceptionfeature aef)7765 EnsPAssemblyexceptionfeature ensAssemblyexceptionfeatureNewCpy(
7766     const EnsPAssemblyexceptionfeature aef)
7767 {
7768     EnsPAssemblyexceptionfeature pthis = NULL;
7769 
7770     AJNEW0(pthis);
7771 
7772     pthis->Use            = 1U;
7773     pthis->Identifier     = aef->Identifier;
7774     pthis->Adaptor        = aef->Adaptor;
7775     pthis->Feature        = ensFeatureNewRef(aef->Feature);
7776     pthis->ExceptionSlice = ensSliceNewRef(aef->ExceptionSlice);
7777     pthis->Type           = aef->Type;
7778 
7779     return pthis;
7780 }
7781 
7782 
7783 
7784 
7785 /* @func ensAssemblyexceptionfeatureNewIni ************************************
7786 **
7787 ** Constructor for an Ensembl Assembly Exception Feature with initial values.
7788 **
7789 ** @cc Bio::EnsEMBL::Storable::new
7790 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
7791 ** Ensembl Assembly Exception Feature Adaptor
7792 ** @param [r] identifier [ajuint] SQL database-internal identifier
7793 ** @cc Bio::EnsEMBL::Feature::new
7794 ** @param [u] feature [EnsPFeature] Ensembl Feature
7795 ** @cc Bio::EnsEMBL::AssemblyExceptionFeature::new
7796 ** @param [u] slice [EnsPSlice] Alternative Slice
7797 ** @param [u] type [EnsEAssemblyexceptionType]
7798 ** Ensembl Assembly Exception Type enumeration
7799 **
7800 ** @return [EnsPAssemblyexceptionfeature]
7801 ** Ensembl Assembly Exception Feature or NULL
7802 **
7803 ** @release 6.4.0
7804 ** @@
7805 ******************************************************************************/
7806 
ensAssemblyexceptionfeatureNewIni(EnsPAssemblyexceptionfeatureadaptor aefa,ajuint identifier,EnsPFeature feature,EnsPSlice slice,EnsEAssemblyexceptionType type)7807 EnsPAssemblyexceptionfeature ensAssemblyexceptionfeatureNewIni(
7808     EnsPAssemblyexceptionfeatureadaptor aefa,
7809     ajuint identifier,
7810     EnsPFeature feature,
7811     EnsPSlice slice,
7812     EnsEAssemblyexceptionType type)
7813 {
7814     EnsPAssemblyexceptionfeature aef = NULL;
7815 
7816     if (!slice)
7817         return NULL;
7818 
7819     if (!type)
7820         return NULL;
7821 
7822     AJNEW0(aef);
7823 
7824     aef->Use            = 1U;
7825     aef->Identifier     = identifier;
7826     aef->Adaptor        = aefa;
7827     aef->Feature        = feature;
7828     aef->ExceptionSlice = ensSliceNewRef(slice);
7829     aef->Type           = type;
7830 
7831     return aef;
7832 }
7833 
7834 
7835 
7836 
7837 /* @func ensAssemblyexceptionfeatureNewRef ************************************
7838 **
7839 ** Ensembl Object referencing function, which returns a pointer to the
7840 ** Ensembl Object passed in and increases its reference count.
7841 **
7842 ** @param [u] aef [EnsPAssemblyexceptionfeature]
7843 ** Ensembl Assembly Exception Feature
7844 **
7845 ** @return [EnsPAssemblyexceptionfeature]
7846 ** Ensembl Assembly Exception Feature or NULL
7847 **
7848 ** @release 6.2.0
7849 ** @@
7850 ******************************************************************************/
7851 
ensAssemblyexceptionfeatureNewRef(EnsPAssemblyexceptionfeature aef)7852 EnsPAssemblyexceptionfeature ensAssemblyexceptionfeatureNewRef(
7853     EnsPAssemblyexceptionfeature aef)
7854 {
7855     if (!aef)
7856         return NULL;
7857 
7858     aef->Use++;
7859 
7860     return aef;
7861 }
7862 
7863 
7864 
7865 
7866 /* @section destructors *******************************************************
7867 **
7868 ** Destruction destroys all internal data structures and frees the memory
7869 ** allocated for an Ensembl Assembly Exception Feature object.
7870 **
7871 ** @fdata [EnsPAssemblyexceptionfeature]
7872 **
7873 ** @nam3rule Del Destroy (free) an Ensembl Assembly Exception Feature
7874 **
7875 ** @argrule * Paef [EnsPAssemblyexceptionfeature*]
7876 ** Ensembl Assembly Exception Feature address
7877 **
7878 ** @valrule * [void]
7879 **
7880 ** @fcategory delete
7881 ******************************************************************************/
7882 
7883 
7884 
7885 
7886 /* @func ensAssemblyexceptionfeatureDel ***************************************
7887 **
7888 ** Default destructor for an Ensembl Assembly Exception Feature.
7889 **
7890 ** @param [d] Paef [EnsPAssemblyexceptionfeature*]
7891 ** Ensembl Assembly Exception Feature address
7892 **
7893 ** @return [void]
7894 **
7895 ** @release 6.2.0
7896 ** @@
7897 ******************************************************************************/
7898 
ensAssemblyexceptionfeatureDel(EnsPAssemblyexceptionfeature * Paef)7899 void ensAssemblyexceptionfeatureDel(EnsPAssemblyexceptionfeature *Paef)
7900 {
7901     EnsPAssemblyexceptionfeature pthis = NULL;
7902 
7903     if (!Paef)
7904         return;
7905 
7906 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
7907     if (ajDebugTest("ensAssemblyexceptionfeatureDel"))
7908     {
7909         ajDebug("ensAssemblyexceptionfeatureDel\n"
7910                 "  *Paef %p\n",
7911                 *Paef);
7912 
7913         ensAssemblyexceptionfeatureTrace(*Paef, 1);
7914     }
7915 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
7916 
7917     if (!(pthis = *Paef) || --pthis->Use)
7918     {
7919         *Paef = NULL;
7920 
7921         return;
7922     }
7923 
7924     ensFeatureDel(&pthis->Feature);
7925 
7926     ensSliceDel(&pthis->ExceptionSlice);
7927 
7928     ajMemFree((void **) Paef);
7929 
7930     return;
7931 }
7932 
7933 
7934 
7935 
7936 /* @section member retrieval **************************************************
7937 **
7938 ** Functions for returning members of an
7939 ** Ensembl Assembly Exception Feature object.
7940 **
7941 ** @fdata [EnsPAssemblyexceptionfeature]
7942 **
7943 ** @nam3rule Get Return Assembly Exception Feature attribute(s)
7944 ** @nam4rule Adaptor Return the Ensembl Assembly Exception Feature Adaptor
7945 ** @nam4rule Exception Return exeption attribute(s)
7946 ** @nam5rule Slice Return the exception Ensembl Slice
7947 ** @nam4rule Feature Return the Ensembl Feature
7948 ** @nam4rule Identifier Return the SQL database-internal identifier
7949 ** @nam4rule Type Return the Ensembl Assembly Exception Type enumeration
7950 **
7951 ** @argrule * aef [const EnsPAssemblyexceptionfeature]
7952 ** Ensembl Assembly Exception Feature
7953 **
7954 ** @valrule Adaptor [EnsPAssemblyexceptionfeatureadaptor]
7955 ** Ensembl Assembly Exception Feature Adaptor or NULL
7956 ** @valrule ExceptionSlice [EnsPSlice]
7957 ** Alternative Ensembl Slice or NULL
7958 ** @valrule Feature [EnsPFeature]
7959 ** Ensembl Feature or NULL
7960 ** @valrule Identifier [ajuint]
7961 ** SQL database-internal identifier or 0
7962 ** @valrule Type [EnsEAssemblyexceptionType]
7963 ** Ensembl Assembly Exception Type or ensEAssemblyexceptionTypeNULL
7964 **
7965 ** @fcategory use
7966 ******************************************************************************/
7967 
7968 
7969 
7970 
7971 /* @func ensAssemblyexceptionfeatureGetAdaptor ********************************
7972 **
7973 ** Get the Ensembl Assembly Exception Feature Adaptor member of an
7974 ** Ensembl Assembly Exception Feature.
7975 **
7976 ** @cc Bio::EnsEMBL::Storable::adaptor
7977 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
7978 ** Ensembl Assembly Exception Feature
7979 **
7980 ** @return [EnsPAssemblyexceptionfeatureadaptor]
7981 ** Ensembl Assembly Exception Feature Adaptor or NULL
7982 **
7983 ** @release 6.2.0
7984 ** @@
7985 ******************************************************************************/
7986 
ensAssemblyexceptionfeatureGetAdaptor(const EnsPAssemblyexceptionfeature aef)7987 EnsPAssemblyexceptionfeatureadaptor ensAssemblyexceptionfeatureGetAdaptor(
7988     const EnsPAssemblyexceptionfeature aef)
7989 {
7990     return (aef) ? aef->Adaptor : NULL;
7991 }
7992 
7993 
7994 
7995 
7996 /* @func ensAssemblyexceptionfeatureGetExceptionSlice *************************
7997 **
7998 ** Get the alternate Ensembl Slice member of an
7999 ** Ensembl Assembly Exception Feature.
8000 **
8001 ** @cc Bio::EnsEMBL::AssemblyExceptionFeature::alternate_slice
8002 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8003 ** Ensembl Assembly Exception Feature
8004 **
8005 ** @return [EnsPSlice] Alternate Ensembl Slice or NULL
8006 **
8007 ** @release 6.4.0
8008 ** @@
8009 ******************************************************************************/
8010 
ensAssemblyexceptionfeatureGetExceptionSlice(const EnsPAssemblyexceptionfeature aef)8011 EnsPSlice ensAssemblyexceptionfeatureGetExceptionSlice(
8012     const EnsPAssemblyexceptionfeature aef)
8013 {
8014     return (aef) ? aef->ExceptionSlice : NULL;
8015 }
8016 
8017 
8018 
8019 
8020 /* @func ensAssemblyexceptionfeatureGetFeature ********************************
8021 **
8022 ** Get the Ensembl Feature member of an Ensembl Assembly Exception Feature.
8023 **
8024 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8025 ** Ensembl Assembly Exception Feature
8026 **
8027 ** @return [EnsPFeature] Ensembl Feature or NULL
8028 **
8029 ** @release 6.2.0
8030 ** @@
8031 ******************************************************************************/
8032 
ensAssemblyexceptionfeatureGetFeature(const EnsPAssemblyexceptionfeature aef)8033 EnsPFeature ensAssemblyexceptionfeatureGetFeature(
8034     const EnsPAssemblyexceptionfeature aef)
8035 {
8036     return (aef) ? aef->Feature : NULL;
8037 }
8038 
8039 
8040 
8041 
8042 /* @func ensAssemblyexceptionfeatureGetIdentifier *****************************
8043 **
8044 ** Get the SQL database-internal identifier member of an
8045 ** Ensembl Assembly Exception Feature.
8046 **
8047 ** @cc Bio::EnsEMBL::Storable::dbID
8048 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8049 ** Ensembl Assembly Exception Feature
8050 **
8051 ** @return [ajuint] SQL database-internal identifier or 0U
8052 **
8053 ** @release 6.2.0
8054 ** @@
8055 ******************************************************************************/
8056 
ensAssemblyexceptionfeatureGetIdentifier(const EnsPAssemblyexceptionfeature aef)8057 ajuint ensAssemblyexceptionfeatureGetIdentifier(
8058     const EnsPAssemblyexceptionfeature aef)
8059 {
8060     return (aef) ? aef->Identifier : 0U;
8061 }
8062 
8063 
8064 
8065 
8066 /* @func ensAssemblyexceptionfeatureGetType ***********************************
8067 **
8068 ** Get the Ensembl Assembly Exception Type enumeration member of an
8069 ** Ensembl Assembly Exception Feature.
8070 **
8071 ** @cc Bio::EnsEMBL::AssemblyExceptionFeature::type
8072 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8073 ** Ensembl Assembly Exception Feature
8074 **
8075 ** @return [EnsEAssemblyexceptionType]
8076 ** Ensembl Assembly Exception Type enumeration or ensEAssemblyexceptionTypeNULL
8077 **
8078 ** @release 6.2.0
8079 ** @@
8080 ******************************************************************************/
8081 
ensAssemblyexceptionfeatureGetType(const EnsPAssemblyexceptionfeature aef)8082 EnsEAssemblyexceptionType ensAssemblyexceptionfeatureGetType(
8083     const EnsPAssemblyexceptionfeature aef)
8084 {
8085     return (aef) ? aef->Type : ensEAssemblyexceptionTypeNULL;
8086 }
8087 
8088 
8089 
8090 
8091 /* @section member assignment *************************************************
8092 **
8093 ** Functions for assigning members of an
8094 ** Ensembl Assembly Exception Feature object.
8095 **
8096 ** @fdata [EnsPAssemblyexceptionfeature]
8097 **
8098 ** @nam3rule Set Set one member of an Assembly Exception Feature
8099 ** @nam4rule Adaptor Set the Ensembl Assembly Exception Feature Adaptor
8100 ** @nam4rule Exception Set exception attribute(s)
8101 ** @nam5rule Slice Set the exception Ensembl Slice
8102 ** @nam4rule Feature Set the Ensembl Feature
8103 ** @nam4rule Identifier Set the SQL database-internal identifier
8104 ** @nam4rule Type Set the Ensembl Assembly Exception Type enumeration
8105 **
8106 ** @argrule * aef [EnsPAssemblyexceptionfeature]
8107 ** Ensembl Assembly Exception Feature
8108 ** @argrule Adaptor aefa [EnsPAssemblyexceptionfeatureadaptor]
8109 ** Ensembl Assembly Exception Feature Adaptor
8110 ** @argrule ExceptionSlice slice [EnsPSlice]
8111 ** Exception Ensembl Slice
8112 ** @argrule Feature feature [EnsPFeature]
8113 ** Ensembl Feature
8114 ** @argrule Identifier identifier [ajuint]
8115 ** SQL database-internal identifier
8116 ** @argrule Type type [EnsEAssemblyexceptionType]
8117 ** Ensembl Assembly Exception Type enumeration
8118 **
8119 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
8120 **
8121 ** @fcategory modify
8122 ******************************************************************************/
8123 
8124 
8125 
8126 
8127 /* @func ensAssemblyexceptionfeatureSetAdaptor ********************************
8128 **
8129 ** Set the Ensembl Assembly Exception Feature Adaptor member of an
8130 ** Ensembl Assembly Exception Feature.
8131 **
8132 ** @cc Bio::EnsEMBL::Storable::adaptor
8133 ** @param [u] aef [EnsPAssemblyexceptionfeature]
8134 ** Ensembl Assembly Exception Feature
8135 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
8136 ** Ensembl Assembly Exception Feature Adaptor
8137 **
8138 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8139 **
8140 ** @release 6.2.0
8141 ** @@
8142 ******************************************************************************/
8143 
ensAssemblyexceptionfeatureSetAdaptor(EnsPAssemblyexceptionfeature aef,EnsPAssemblyexceptionfeatureadaptor aefa)8144 AjBool ensAssemblyexceptionfeatureSetAdaptor(
8145     EnsPAssemblyexceptionfeature aef,
8146     EnsPAssemblyexceptionfeatureadaptor aefa)
8147 {
8148     if (!aef)
8149         return ajFalse;
8150 
8151     aef->Adaptor = aefa;
8152 
8153     return ajTrue;
8154 }
8155 
8156 
8157 
8158 
8159 /* @func ensAssemblyexceptionfeatureSetExceptionSlice *************************
8160 **
8161 ** Set the alternate Ensembl Slice member of an
8162 ** Ensembl Assembly Exception Feature.
8163 **
8164 ** @param [u] aef [EnsPAssemblyexceptionfeature]
8165 ** Ensembl Assembly Exception Feature
8166 ** @param [u] slice [EnsPSlice] Exception Ensembl Slice
8167 **
8168 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8169 **
8170 ** @release 6.4.0
8171 ** @@
8172 ******************************************************************************/
8173 
ensAssemblyexceptionfeatureSetExceptionSlice(EnsPAssemblyexceptionfeature aef,EnsPSlice slice)8174 AjBool ensAssemblyexceptionfeatureSetExceptionSlice(
8175     EnsPAssemblyexceptionfeature aef,
8176     EnsPSlice slice)
8177 {
8178     if (!aef)
8179         return ajFalse;
8180 
8181     ensSliceDel(&aef->ExceptionSlice);
8182 
8183     aef->ExceptionSlice = ensSliceNewRef(slice);
8184 
8185     return ajTrue;
8186 }
8187 
8188 
8189 
8190 
8191 /* @func ensAssemblyexceptionfeatureSetFeature ********************************
8192 **
8193 ** Set the Ensembl Feature member of an Ensembl Assembly Exception Feature.
8194 **
8195 ** @param [u] aef [EnsPAssemblyexceptionfeature]
8196 ** Ensembl Assembly Exception Feature
8197 ** @param [u] feature [EnsPFeature] Ensembl Feature
8198 **
8199 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8200 **
8201 ** @release 6.2.0
8202 ** @@
8203 ******************************************************************************/
8204 
ensAssemblyexceptionfeatureSetFeature(EnsPAssemblyexceptionfeature aef,EnsPFeature feature)8205 AjBool ensAssemblyexceptionfeatureSetFeature(
8206     EnsPAssemblyexceptionfeature aef,
8207     EnsPFeature feature)
8208 {
8209     if (!aef)
8210         return ajFalse;
8211 
8212     ensFeatureDel(&aef->Feature);
8213 
8214     aef->Feature = ensFeatureNewRef(feature);
8215 
8216     return ajTrue;
8217 }
8218 
8219 
8220 
8221 
8222 /* @func ensAssemblyexceptionfeatureSetIdentifier *****************************
8223 **
8224 ** Set the SQL database-internal identifier member of an
8225 ** Ensembl Assembly Exception Feature.
8226 **
8227 ** @cc Bio::EnsEMBL::Storable::dbID
8228 ** @param [u] aef [EnsPAssemblyexceptionfeature]
8229 ** Ensembl Assembly Exception Feature
8230 ** @param [r] identifier [ajuint] SQL database-internal identifier
8231 **
8232 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8233 **
8234 ** @release 6.2.0
8235 ** @@
8236 ******************************************************************************/
8237 
ensAssemblyexceptionfeatureSetIdentifier(EnsPAssemblyexceptionfeature aef,ajuint identifier)8238 AjBool ensAssemblyexceptionfeatureSetIdentifier(
8239     EnsPAssemblyexceptionfeature aef,
8240     ajuint identifier)
8241 {
8242     if (!aef)
8243         return ajFalse;
8244 
8245     aef->Identifier = identifier;
8246 
8247     return ajTrue;
8248 }
8249 
8250 
8251 
8252 
8253 /* @func ensAssemblyexceptionfeatureSetType ***********************************
8254 **
8255 ** Set the Ensembl Assembly Exception Type enumeration member of an
8256 ** Ensembl Assembly Exception Feature.
8257 **
8258 ** @param [u] aef [EnsPAssemblyexceptionfeature]
8259 ** Ensembl Assembly Exception Feature
8260 ** @param [u] type [EnsEAssemblyexceptionType]
8261 ** Ensembl Assembly Exception Type enumeration
8262 **
8263 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8264 **
8265 ** @release 6.2.0
8266 ** @@
8267 ******************************************************************************/
8268 
ensAssemblyexceptionfeatureSetType(EnsPAssemblyexceptionfeature aef,EnsEAssemblyexceptionType type)8269 AjBool ensAssemblyexceptionfeatureSetType(EnsPAssemblyexceptionfeature aef,
8270                                           EnsEAssemblyexceptionType type)
8271 {
8272     if (!aef)
8273         return ajFalse;
8274 
8275     aef->Type = type;
8276 
8277     return ajTrue;
8278 }
8279 
8280 
8281 
8282 
8283 /* @section debugging *********************************************************
8284 **
8285 ** Functions for reporting of an Ensembl Assembly Exception Feature object.
8286 **
8287 ** @fdata [EnsPAssemblyexceptionfeature]
8288 **
8289 ** @nam3rule Trace Report Ensembl Assembly Exception Feature members to
8290 **                 debug file
8291 **
8292 ** @argrule Trace aef [const EnsPAssemblyexceptionfeature]
8293 ** Ensembl Assembly Exception Feature
8294 ** @argrule Trace level [ajuint] Indentation level
8295 **
8296 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
8297 **
8298 ** @fcategory misc
8299 ******************************************************************************/
8300 
8301 
8302 
8303 
8304 /* @func ensAssemblyexceptionfeatureTrace *************************************
8305 **
8306 ** Trace an Ensembl Assembly Exception Feature.
8307 **
8308 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8309 ** Ensembl Assembly Exception Feature
8310 ** @param [r] level [ajuint] Indentation level
8311 **
8312 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8313 **
8314 ** @release 6.2.0
8315 ** @@
8316 ******************************************************************************/
8317 
ensAssemblyexceptionfeatureTrace(const EnsPAssemblyexceptionfeature aef,ajuint level)8318 AjBool ensAssemblyexceptionfeatureTrace(const EnsPAssemblyexceptionfeature aef,
8319                                         ajuint level)
8320 {
8321     AjPStr indent = NULL;
8322 
8323     if (!aef)
8324         return ajFalse;
8325 
8326     indent = ajStrNew();
8327 
8328     ajStrAppendCountK(&indent, ' ', level * 2);
8329 
8330     ajDebug("ensAssemblyexceptionfeatureTrace %p\n"
8331             "%S  Use %u\n"
8332             "%S  Identifier %u\n"
8333             "%S  Adaptor %p\n"
8334             "%S  Feature %p\n"
8335             "%S  ExceptionSlice %p\n"
8336             "%S  Type '%s'\n",
8337             indent, aef,
8338             indent, aef->Use,
8339             indent, aef->Identifier,
8340             indent, aef->Adaptor,
8341             indent, aef->Feature,
8342             indent, aef->ExceptionSlice,
8343             indent, ensAssemblyexceptionTypeToChar(aef->Type));
8344 
8345     ensFeatureTrace(aef->Feature, level + 1);
8346 
8347     ensSliceTrace(aef->ExceptionSlice, level + 1);
8348 
8349     ajStrDel(&indent);
8350 
8351     return ajTrue;
8352 }
8353 
8354 
8355 
8356 
8357 /* @section calculate *********************************************************
8358 **
8359 ** Functions for calculating information from an
8360 ** Ensembl Assembly Exception Feature object.
8361 **
8362 ** @fdata [EnsPAssemblyexceptionfeature]
8363 **
8364 ** @nam3rule Calculate Calculate Ensembl Assembly Exception Feature information
8365 ** @nam4rule Memsize Calculate the memory size in bytes
8366 **
8367 ** @argrule * aef [const EnsPAssemblyexceptionfeature]
8368 ** Ensembl Assembly Exception Feature
8369 **
8370 ** @valrule Memsize [size_t] Memory size in bytes or 0
8371 **
8372 ** @fcategory misc
8373 ******************************************************************************/
8374 
8375 
8376 
8377 
8378 /* @func ensAssemblyexceptionfeatureCalculateMemsize **************************
8379 **
8380 ** Calculate the memory size in bytes of an Ensembl Assembly Exception Feature.
8381 **
8382 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8383 ** Ensembl Assembly Exception Feature
8384 **
8385 ** @return [size_t] Memory size in bytes or 0
8386 **
8387 ** @release 6.4.0
8388 ** @@
8389 ******************************************************************************/
8390 
ensAssemblyexceptionfeatureCalculateMemsize(const EnsPAssemblyexceptionfeature aef)8391 size_t ensAssemblyexceptionfeatureCalculateMemsize(
8392     const EnsPAssemblyexceptionfeature aef)
8393 {
8394     size_t size = 0;
8395 
8396     if (!aef)
8397         return 0;
8398 
8399     size += sizeof (EnsOAssemblyexceptionfeature);
8400 
8401     size += ensFeatureCalculateMemsize(aef->Feature);
8402 
8403     size += ensSliceCalculateMemsize(aef->ExceptionSlice);
8404 
8405     return size;
8406 }
8407 
8408 
8409 
8410 
8411 /* @section fetch *************************************************************
8412 **
8413 ** Functions for fetching objects of an
8414 ** Ensembl Assembly Exception Feature object.
8415 **
8416 ** @fdata [EnsPAssemblyexceptionfeature]
8417 **
8418 ** @nam3rule Fetch Fetch object from an Ensembl Assembly Exception Feature
8419 ** @nam4rule Displayidentifier Fetch the display identifier
8420 **
8421 ** @argrule * aef [const EnsPAssemblyexceptionfeature]
8422 ** Ensembl Assembly Exception Feature
8423 ** @argrule Displayidentifier Pidentifier [AjPStr*] Display identifier address
8424 **
8425 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
8426 **
8427 ** @fcategory misc
8428 ******************************************************************************/
8429 
8430 
8431 
8432 
8433 /* @func ensAssemblyexceptionfeatureFetchDisplayidentifier ********************
8434 **
8435 ** Fetch the display identifier of an Ensembl Assembly Exception Feature.
8436 **
8437 ** The caller is responsible for deletiung the AJAX String.
8438 **
8439 ** @param [r] aef [const EnsPAssemblyexceptionfeature]
8440 ** Ensembl Assembly Exception Feature
8441 ** @param [wP] Pidentifier [AjPStr*] Display identifier String address
8442 **
8443 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8444 **
8445 ** @release 6.4.0
8446 ** @@
8447 ******************************************************************************/
8448 
ensAssemblyexceptionfeatureFetchDisplayidentifier(const EnsPAssemblyexceptionfeature aef,AjPStr * Pidentifier)8449 AjBool ensAssemblyexceptionfeatureFetchDisplayidentifier(
8450     const EnsPAssemblyexceptionfeature aef,
8451     AjPStr *Pidentifier)
8452 {
8453     if (!aef)
8454         return ajFalse;
8455 
8456     if (!Pidentifier)
8457         return ajFalse;
8458 
8459     if (!aef->ExceptionSlice)
8460         return ajFalse;
8461 
8462     if (*Pidentifier)
8463         ajStrAssignS(
8464             Pidentifier,
8465             ensSliceGetSeqregionName(aef->ExceptionSlice));
8466     else
8467         *Pidentifier = ajStrNewS(
8468             ensSliceGetSeqregionName(aef->ExceptionSlice));
8469 
8470     return ajTrue;
8471 }
8472 
8473 
8474 
8475 
8476 /* @datasection [EnsPAssemblyexceptionfeatureadaptor] Ensembl Assembly
8477 ** Exception Feature Adaptor
8478 **
8479 ** @nam2rule Assemblyexceptionfeatureadaptor Functions for manipulating
8480 ** Ensembl Assembly Exception Feature Adaptor objects
8481 **
8482 ** @cc Bio::EnsEMBL::DBSQL::AssemblyExceptionFeatureAdaptor
8483 ** @cc CVS Revision: 1.21
8484 ** @cc CVS Tag: branch-ensembl-68
8485 **
8486 ******************************************************************************/
8487 
8488 
8489 
8490 
8491 /* @funcstatic assemblyexceptionfeatureadaptorCacheInit ***********************
8492 **
8493 ** Initialise an Ensembl Assembly Exception Feature Adaptor-internal
8494 ** Ensembl Assembly Exception Feature cache.
8495 **
8496 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
8497 ** Ensembl Assembly Exception Feature Adaptor
8498 **
8499 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8500 **
8501 ** @release 6.3.0
8502 ** @@
8503 ******************************************************************************/
8504 
assemblyexceptionfeatureadaptorCacheInit(EnsPAssemblyexceptionfeatureadaptor aefa)8505 static AjBool assemblyexceptionfeatureadaptorCacheInit(
8506     EnsPAssemblyexceptionfeatureadaptor aefa)
8507 {
8508     ajuint erid    = 0U;
8509     ajuint srid    = 0U;
8510     ajuint erstart = 0U;
8511     ajuint srstart = 0U;
8512     ajuint erend   = 0U;
8513     ajuint srend   = 0U;
8514 
8515     ajuint *Pidentifier = NULL;
8516 
8517     AjPList aes = NULL;
8518 
8519     EnsPAssemblyexception ae         = NULL;
8520     EnsPAssemblyexceptionadaptor aea = NULL;
8521 
8522     EnsPAssemblyexceptionfeature refaef = NULL;
8523     EnsPAssemblyexceptionfeature excaef = NULL;
8524 
8525     EnsPDatabaseadaptor dba = NULL;
8526 
8527     EnsPFeature feature = NULL;
8528 
8529     EnsPSlice excslice   = NULL;
8530     EnsPSlice refslice   = NULL;
8531     EnsPSliceadaptor sla = NULL;
8532 
8533     if (!aefa)
8534         return ajFalse;
8535 
8536     if (!aefa->CacheByIdentifier)
8537     {
8538         ajDebug("assemblyexceptionfeatureadaptorCacheInit CacheByIdentifier "
8539                 "not initialised!\n");
8540 
8541         return ajFalse;
8542     }
8543 
8544     dba = ensAssemblyexceptionfeatureadaptorGetDatabaseadaptor(aefa);
8545 
8546     aea = ensRegistryGetAssemblyexceptionadaptor(dba);
8547     sla = ensRegistryGetSliceadaptor(dba);
8548 
8549     aes = ajListNew();
8550 
8551     ensAssemblyexceptionadaptorFetchAll(aea, aes);
8552 
8553     while (ajListPop(aes, (void **) &ae))
8554     {
8555         srid = ensAssemblyexceptionGetReferenceSeqregion(ae);
8556 
8557         srstart = ensAssemblyexceptionGetReferenceStart(ae);
8558 
8559         srend = ensAssemblyexceptionGetReferenceEnd(ae);
8560 
8561         erid = ensAssemblyexceptionGetExceptionSeqregion(ae);
8562 
8563         erstart = ensAssemblyexceptionGetExceptionStart(ae);
8564 
8565         erend = ensAssemblyexceptionGetExceptionEnd(ae);
8566 
8567         /*
8568         ** Each Ensembl Assembly Exception creates two
8569         ** Ensembl Assembly Exception Feature objects, each of which has
8570         ** an alternative Slice pointing to the "other" one. Thereby, the
8571         ** Feature is annotated on the Slice spanning the entire
8572         ** Ensembl Sequence Region. The alternate Slice spans only the
8573         ** exception region.
8574         */
8575 
8576         /* For the reference Slice ... */
8577 
8578         ensSliceadaptorFetchBySeqregionIdentifier(sla,
8579                                                   srid,
8580                                                   0,
8581                                                   0,
8582                                                   0,
8583                                                   &refslice);
8584 
8585         ensSliceadaptorFetchBySeqregionIdentifier(sla,
8586                                                   erid,
8587                                                   erstart,
8588                                                   erend,
8589                                                   0,
8590                                                   &excslice);
8591 
8592         feature = ensFeatureNewIniS((EnsPAnalysis) NULL,
8593                                     refslice,
8594                                     srstart,
8595                                     srend,
8596                                     1);
8597 
8598         refaef = ensAssemblyexceptionfeatureNewIni(
8599             aefa,
8600             ensAssemblyexceptionGetIdentifier(ae),
8601             feature,
8602             excslice,
8603             ensAssemblyexceptionGetType(ae));
8604 
8605         ensFeatureDel(&feature);
8606 
8607         ensSliceDel(&excslice);
8608 
8609         ensSliceDel(&refslice);
8610 
8611         /* Insert the (reference) Assembly Exception Feature into the cache. */
8612 
8613         ajListPushAppend(aefa->Cache, (void *) refaef);
8614 
8615         AJNEW0(Pidentifier);
8616 
8617         *Pidentifier = refaef->Identifier;
8618 
8619         ajTablePut(aefa->CacheByIdentifier,
8620                    (void *) Pidentifier,
8621                    (void *) ensAssemblyexceptionfeatureNewRef(refaef));
8622 
8623         /* For the exception Slice ... */
8624 
8625         ensSliceadaptorFetchBySeqregionIdentifier(sla,
8626                                                   erid,
8627                                                   0,
8628                                                   0,
8629                                                   0,
8630                                                   &excslice);
8631 
8632         ensSliceadaptorFetchBySeqregionIdentifier(sla,
8633                                                   srid,
8634                                                   srstart,
8635                                                   srend,
8636                                                   0,
8637                                                   &refslice);
8638 
8639         feature = ensFeatureNewIniS((EnsPAnalysis) NULL,
8640                                     excslice,
8641                                     erstart,
8642                                     erend,
8643                                     1);
8644 
8645         excaef = ensAssemblyexceptionfeatureNewIni(
8646             aefa,
8647             ensAssemblyexceptionGetIdentifier(ae),
8648             feature,
8649             refslice,
8650             ensAssemblyexceptionGetType(ae));
8651 
8652         ensFeatureDel(&feature);
8653 
8654         ensSliceDel(&excslice);
8655 
8656         ensSliceDel(&refslice);
8657 
8658         /* Insert the (exception) Assembly Exception Feature into the cache. */
8659 
8660         ajListPushAppend(aefa->Cache, (void *) excaef);
8661 
8662         ensAssemblyexceptionDel(&ae);
8663     }
8664 
8665     ajListFree(&aes);
8666 
8667     return ajTrue;
8668 }
8669 
8670 
8671 
8672 
8673 /* @section constructors ******************************************************
8674 **
8675 ** All constructors return a new Ensembl Assembly Exception Feature Adaptor
8676 ** by pointer.
8677 ** It is the responsibility of the user to first destroy any previous
8678 ** Assembly Exception Feature Adaptor. The target pointer does not need to be
8679 ** initialised to NULL, but it is good programming practice to do so anyway
8680 **
8681 ** @fdata [EnsPAssemblyexceptionfeatureadaptor]
8682 **
8683 ** @nam3rule New Constructor
8684 **
8685 ** @argrule New dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
8686 ** @argrule Obj object [EnsPAssemblyexceptionfeature]
8687 ** Ensembl Assembly Exception Feature Adaptor
8688 ** @argrule Ref object [EnsPAssemblyexceptionfeature]
8689 ** Ensembl Assembly Exception Feature Adaptor
8690 **
8691 ** @valrule * [EnsPAssemblyexceptionfeatureadaptor]
8692 ** Ensembl Assembly Exception Feature Adaptor or NULL
8693 **
8694 ** @fcategory new
8695 ******************************************************************************/
8696 
8697 
8698 
8699 
8700 /* @func ensAssemblyexceptionfeatureadaptorNew ********************************
8701 **
8702 ** Default constructor for an Ensembl Assembly Exception Feature Adaptor.
8703 **
8704 ** Ensembl Object Adaptors are singleton objects in the sense that a single
8705 ** instance of an Ensembl Object Adaptor connected to a particular database is
8706 ** sufficient to instantiate any number of Ensembl Objects from the database.
8707 ** Each Ensembl Object will have a weak reference to the Object Adaptor that
8708 ** instantiated it. Therefore, Ensembl Object Adaptors should not be
8709 ** instantiated directly, but rather obtained from the Ensembl Registry,
8710 ** which will in turn call this function if neccessary.
8711 **
8712 ** @see ensRegistryGetDatabaseadaptor
8713 ** @see ensRegistryGetAssemblyexceptionfeatureadaptor
8714 **
8715 ** @cc Bio::EnsEMBL::DBSQL::AssemblyExceptionFeatureAdaptor::new
8716 ** @param [u] dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
8717 **
8718 ** @return [EnsPAssemblyexceptionfeatureadaptor]
8719 ** Ensembl Assembly Exception Feature Adaptor or NULL
8720 **
8721 ** @release 6.2.0
8722 ** @@
8723 ******************************************************************************/
8724 
ensAssemblyexceptionfeatureadaptorNew(EnsPDatabaseadaptor dba)8725 EnsPAssemblyexceptionfeatureadaptor ensAssemblyexceptionfeatureadaptorNew(
8726     EnsPDatabaseadaptor dba)
8727 {
8728     EnsPAssemblyexceptionfeatureadaptor aefa = NULL;
8729 
8730     if (!dba)
8731         return NULL;
8732 
8733     AJNEW0(aefa);
8734 
8735     aefa->Adaptor = dba;
8736 
8737     aefa->Cache = ajListNew();
8738 
8739     aefa->CacheByIdentifier = ajTableuintNew(0U);
8740 
8741     ajTableSetDestroyvalue(
8742         aefa->CacheByIdentifier,
8743         (void (*)(void **)) &ensAssemblyexceptionfeatureDel);
8744 
8745     aefa->CacheBySlice = ensCacheNew(
8746         ensECacheTypeAlphaNumeric,
8747         assemblyexceptionfeatureadaptorKCacheMaxBytes,
8748         assemblyexceptionfeatureadaptorKCacheMaxCount,
8749         assemblyexceptionfeatureadaptorKCacheMaxSize,
8750         (void *(*)(void *value))
8751         &ensAssemblyexceptionfeatureNewRef,
8752         (void (*)(void **Pvalue))
8753         &ensAssemblyexceptionfeatureDel,
8754         (size_t (*)(const void *value))
8755         &ensAssemblyexceptionfeatureCalculateMemsize,
8756         (void *(*)(const void *key)) NULL,
8757         (AjBool (*)(const void *value)) NULL,
8758         ajFalse,
8759         "Assembly Exception Feature");
8760 
8761     assemblyexceptionfeatureadaptorCacheInit(aefa);
8762 
8763     return aefa;
8764 }
8765 
8766 
8767 
8768 
8769 /* @section destructors *******************************************************
8770 **
8771 ** Destruction destroys all internal data structures and frees the memory
8772 ** allocated for an Ensembl Assembly Exception Feature Adaptor object.
8773 **
8774 ** @fdata [EnsPAssemblyexceptionfeatureadaptor]
8775 **
8776 ** @nam3rule Del Destroy (free) an
8777 ** Ensembl Assembly Exception Feature Adaptor
8778 **
8779 ** @argrule * Paefa [EnsPAssemblyexceptionfeatureadaptor*]
8780 ** Ensembl Assembly Exception Feature Adaptor address
8781 **
8782 ** @valrule * [void]
8783 **
8784 ** @fcategory delete
8785 ******************************************************************************/
8786 
8787 
8788 
8789 
8790 /* @func ensAssemblyexceptionfeatureadaptorDel ********************************
8791 **
8792 ** Default destructor for an Ensembl Assembly Exception Feature Adaptor.
8793 **
8794 ** Ensembl Object Adaptors are singleton objects that are registered in the
8795 ** Ensembl Registry and weakly referenced by Ensembl Objects that have been
8796 ** instantiated by it. Therefore, Ensembl Object Adaptors should never be
8797 ** destroyed directly. Upon exit, the Ensembl Registry will call this function
8798 ** if required.
8799 **
8800 ** @param [d] Paefa [EnsPAssemblyexceptionfeatureadaptor*]
8801 ** Ensembl Assembly Exception Feature Adaptor address
8802 **
8803 ** @return [void]
8804 **
8805 ** @release 6.2.0
8806 ** @@
8807 ******************************************************************************/
8808 
ensAssemblyexceptionfeatureadaptorDel(EnsPAssemblyexceptionfeatureadaptor * Paefa)8809 void ensAssemblyexceptionfeatureadaptorDel(
8810     EnsPAssemblyexceptionfeatureadaptor *Paefa)
8811 {
8812     EnsPAssemblyexceptionfeature        aef   = NULL;
8813     EnsPAssemblyexceptionfeatureadaptor pthis = NULL;
8814 
8815     if (!Paefa)
8816         return;
8817 
8818 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
8819     if (ajDebugTest("ensAssemblyexceptionfeatureadaptorDel"))
8820         ajDebug("ensAssemblyexceptionfeatureadaptorDel\n"
8821                 "  *Paefa %p\n",
8822                 *Paefa);
8823 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
8824 
8825     if (!(pthis = *Paefa))
8826         return;
8827 
8828     while (ajListPop(pthis->Cache, (void **) &aef))
8829         ensAssemblyexceptionfeatureDel(&aef);
8830 
8831     ajTableClearDelete(pthis->CacheByIdentifier);
8832 
8833     ajMemFree((void **) Paefa);
8834 
8835     return;
8836 }
8837 
8838 
8839 
8840 
8841 /* @section member retrieval **************************************************
8842 **
8843 ** Functions for returning members of an
8844 ** Ensembl Assembly Exception Feature Adaptor object.
8845 **
8846 ** @fdata [EnsPAssemblyexceptionfeatureadaptor]
8847 **
8848 ** @nam3rule Get Return Ensembl Assembly Exception Feature Adaptor attribute(s)
8849 ** @nam4rule Baseadaptor Return the Ensembl Base Adaptor
8850 ** @nam4rule Databaseadaptor Return the Ensembl Database Adaptor
8851 **
8852 ** @argrule * aefa [EnsPAssemblyexceptionfeatureadaptor]
8853 ** Ensembl Assembly Exception Feature Adaptor
8854 **
8855 ** @valrule Baseadaptor [EnsPBaseadaptor]
8856 ** Ensembl Base Adaptor or NULL
8857 ** @valrule Databaseadaptor [EnsPDatabaseadaptor]
8858 ** Ensembl Database Adaptor or NULL
8859 **
8860 ** @fcategory use
8861 ******************************************************************************/
8862 
8863 
8864 
8865 
8866 /* @func ensAssemblyexceptionfeatureadaptorGetDatabaseadaptor *****************
8867 **
8868 ** Get the Ensembl Database Adaptor member of an
8869 ** Ensembl Assembly Exception Feature Adaptor.
8870 **
8871 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
8872 ** Ensembl Assembly Exception Feature Adaptor
8873 **
8874 ** @return [EnsPDatabaseadaptor] Ensembl Database Adaptor or NULL
8875 **
8876 ** @release 6.4.0
8877 ** @@
8878 ******************************************************************************/
8879 
ensAssemblyexceptionfeatureadaptorGetDatabaseadaptor(EnsPAssemblyexceptionfeatureadaptor aefa)8880 EnsPDatabaseadaptor ensAssemblyexceptionfeatureadaptorGetDatabaseadaptor(
8881     EnsPAssemblyexceptionfeatureadaptor aefa)
8882 {
8883     return (aefa) ? aefa->Adaptor : NULL;
8884 }
8885 
8886 
8887 
8888 
8889 /* @section object retrieval **************************************************
8890 **
8891 ** Functions for fetching Ensembl Assembly Exception Feature objects from an
8892 ** Ensembl SQL database.
8893 **
8894 ** @fdata [EnsPAssemblyexceptionfeatureadaptor]
8895 **
8896 ** @nam3rule Fetch Fetch Ensembl Assembly Exception Feature object(s)
8897 ** @nam4rule All   Fetch all Ensembl Assembly Exception Feature objects
8898 ** @nam4rule Allby Fetch all Ensembl Assembly Exception Feature objects
8899 **                 matching a criterion
8900 ** @nam5rule Slice Fetch by an Ensembl Slice
8901 ** @nam4rule By    Fetch one Ensembl Assembly Exception Feature object
8902 **                 matching a criterion
8903 ** @nam5rule Identifier Fetch by an SQL database-internal identifier
8904 **
8905 ** @argrule * aefa [EnsPAssemblyexceptionfeatureadaptor]
8906 ** Ensembl Assembly Exception Feature Adaptor
8907 ** @argrule All aefs [AjPList]
8908 ** AJAX List of Ensembl Assembly Exception Feature objects
8909 ** @argrule AllbySlice slice [EnsPSlice]
8910 ** Ensembl Slice
8911 ** @argrule AllbySlice aefs [AjPList]
8912 ** AJAX List of Ensembl Assembly Exception Feature objects
8913 ** @argrule ByIdentifier identifier [ajuint]
8914 ** SQL database-internal identifier
8915 ** @argrule ByIdentifier Paef [EnsPAssemblyexceptionfeature*]
8916 ** Ensembl Assembly Exception Feature address
8917 **
8918 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
8919 **
8920 ** @fcategory use
8921 ******************************************************************************/
8922 
8923 
8924 
8925 
8926 /* @func ensAssemblyexceptionfeatureadaptorFetchAll ***************************
8927 **
8928 ** Fetch all Ensembl Assembly Exception Feature objects.
8929 **
8930 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
8931 ** Ensembl Assembly Exception Feature Adaptor
8932 ** @param [u] aefs [AjPList]
8933 ** AJAX List of Ensembl Assembly Exception Feature objects
8934 **
8935 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8936 **
8937 ** @release 6.2.0
8938 ** @@
8939 ******************************************************************************/
8940 
ensAssemblyexceptionfeatureadaptorFetchAll(EnsPAssemblyexceptionfeatureadaptor aefa,AjPList aefs)8941 AjBool ensAssemblyexceptionfeatureadaptorFetchAll(
8942     EnsPAssemblyexceptionfeatureadaptor aefa,
8943     AjPList aefs)
8944 {
8945     AjIList iter = NULL;
8946 
8947     EnsPAssemblyexceptionfeature aef = NULL;
8948 
8949     if (!aefa)
8950         return ajFalse;
8951 
8952     if (!aefs)
8953         return ajFalse;
8954 
8955     iter = ajListIterNewread(aefa->Cache);
8956 
8957     while (!ajListIterDone(iter))
8958     {
8959         aef = (EnsPAssemblyexceptionfeature) ajListIterGet(iter);
8960 
8961         ajListPushAppend(aefs,
8962                          (void *) ensAssemblyexceptionfeatureNewRef(aef));
8963     }
8964 
8965     ajListIterDel(&iter);
8966 
8967     return ajTrue;
8968 }
8969 
8970 
8971 
8972 
8973 /* @funcstatic assemblyexceptionfeatureadaptorRemap ***************************
8974 **
8975 ** Remap Ensembl Assembly Exception Feature objects onto an Ensembl Slice.
8976 **
8977 ** @cc Bio::EnsEMBL::DBSQL::AssemblyExceptionFeatureAdaptor::_remap
8978 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
8979 ** Ensembl Assembly Exception Feature Adaptor
8980 ** @param [u] aefs [AjPList]
8981 ** AJAX List of Ensembl Assembly Exception Feature objects
8982 ** @param [uN] am [EnsPAssemblymapper] Ensembl Assembly Mapper
8983 ** @param [u] slice [EnsPSlice] Ensembl Slice
8984 **
8985 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
8986 **
8987 ** @release 6.3.0
8988 ** @@
8989 ******************************************************************************/
8990 
assemblyexceptionfeatureadaptorRemap(EnsPAssemblyexceptionfeatureadaptor aefa,AjPList aefs,EnsPAssemblymapper am,EnsPSlice slice)8991 static AjBool assemblyexceptionfeatureadaptorRemap(
8992     EnsPAssemblyexceptionfeatureadaptor aefa,
8993     AjPList aefs,
8994     EnsPAssemblymapper am,
8995     EnsPSlice slice)
8996 {
8997     ajint start  = 0;
8998     ajint end    = 0;
8999     ajint strand = 0;
9000 
9001     ajuint srid = 0U;
9002 
9003     AjIList iter = NULL;
9004     AjPList mrs  = NULL;
9005 
9006     EnsPAssemblyexceptionfeature aef = NULL;
9007 
9008     EnsPFeature feature = NULL;
9009 
9010     EnsPMapperresult mr = NULL;
9011 
9012     if (!aefa)
9013         return ajFalse;
9014 
9015     if (!aefs)
9016         return ajFalse;
9017 
9018     if (!slice)
9019         return ajFalse;
9020 
9021     /*
9022     ** Remapping is not required, if the AJAX List is empty or the Slice
9023     ** attached to the first Feature is already identical to the Slice
9024     ** the Feature objects should be mapped to.
9025     */
9026 
9027     if (!ajListGetLength(aefs))
9028         return ajTrue;
9029 
9030     ajListPeekFirst(aefs, (void **) &aef);
9031 
9032     feature = aef->Feature;
9033 
9034     if (ensSliceMatch(ensFeatureGetSlice(feature), slice))
9035         return ajTrue;
9036 
9037     /* Remapping has not been done, we have to do our own conversion. */
9038 
9039     mrs = ajListNew();
9040 
9041     iter = ajListIterNew(aefs);
9042 
9043     while (!ajListIterDone(iter))
9044     {
9045         aef = (EnsPAssemblyexceptionfeature) ajListIterGet(iter);
9046 
9047         feature = aef->Feature;
9048 
9049         /*
9050         ** Since Feature objects were obtained in contig coordinates, the
9051         ** attached Sequence Region is a contig.
9052         */
9053 
9054         if (!feature->Slice)
9055             ajFatal("assemblyexceptionfeatureadaptorRemap got an "
9056                     "Ensembl Feature (%p) without an Ensembl Slice.\n",
9057                     feature);
9058 
9059         if (ensCoordsystemMatch(ensSliceGetCoordsystemObject(slice),
9060                                 ensSliceGetCoordsystemObject(feature->Slice)))
9061         {
9062             /*
9063             ** The Slice attached to the Feature is in the same
9064             ** Coordinate System as the target Slice, therefore remapping and
9065             ** an Ensembl Assembly Mapper are not required. Nevertheless,
9066             ** coordinates need still adjusting to the Slice.
9067             */
9068 
9069             srid   = ensSliceGetSeqregionIdentifier(feature->Slice);
9070             start  = feature->Start;
9071             end    = feature->End;
9072             strand = feature->Strand;
9073         }
9074         else
9075         {
9076             /*
9077             ** The Slice attached to the Feature is in a different
9078             ** Coordinate System, therefore remapping is required.
9079             */
9080 
9081             if (!am)
9082                 ajFatal("assemblyexceptionfeatureadaptorRemap requires an "
9083                         "Ensembl Assembly Mapper, when "
9084                         "Coordinate System objects of Feature objects and "
9085                         "Slice differ.\n");
9086 
9087             ensAssemblymapperMapSeqregion(am,
9088                                           ensSliceGetSeqregion(feature->Slice),
9089                                           feature->Start,
9090                                           feature->End,
9091                                           feature->Strand,
9092                                           ajTrue,
9093                                           mrs);
9094 
9095             /*
9096             ** The ensAssemblymapperMapSeqregion function in fastmap mode
9097             ** returns at maximum one Ensembl Mapper Result.
9098             ** An empty AJAX List of Ensembl Mapper Result objects
9099             ** means a gap, so remove the Ensembl Object from the AJAX List
9100             ** of Ensembl Objects and delete it.
9101             */
9102 
9103             if (ajListGetLength(mrs))
9104             {
9105                 ajListPeekFirst(mrs, (void **) &mr);
9106 
9107                 srid   = ensMapperresultGetObjectidentifier(mr);
9108                 start  = ensMapperresultGetCoordinateStart(mr);
9109                 end    = ensMapperresultGetCoordinateEnd(mr);
9110                 strand = ensMapperresultGetCoordinateStrand(mr);
9111 
9112                 while (ajListPop(mrs, (void **) &mr))
9113                     ensMapperresultDel(&mr);
9114             }
9115             else
9116             {
9117                 ajListIterRemove(iter);
9118 
9119                 ensAssemblyexceptionfeatureDel(&aef);
9120 
9121                 continue;
9122             }
9123         }
9124 
9125         if ((srid != ensSliceGetSeqregionIdentifier(slice)) ||
9126             (start > ensSliceGetEnd(slice)) ||
9127             (end   < ensSliceGetStart(slice)))
9128         {
9129             /*
9130             ** Since the Feature maps to a region outside the desired area,
9131             ** remove the Ensembl Object from the AJAX List and delete it.
9132             */
9133 
9134             ajListIterRemove(iter);
9135 
9136             ensAssemblyexceptionfeatureDel(&aef);
9137 
9138             continue;
9139         }
9140 
9141         /*
9142         ** FIXME: In contrast to the Perl API the Assembly Exception Feature
9143         ** Adaptor does currently not use a Slice cache. While the Perl API
9144         ** keeps Feature objects on Slice objects spanning the entire
9145         ** Sequence Region, a new copy of the Feature needs to be placed on
9146         ** the requested Slice.
9147         ** Since we are currently not using a Slice cache, the Feature can be
9148         ** remapped in place.
9149         ** FIXME: This means in fact that this function is now again
9150         ** completely identical to the ensFeatureadaptorRemap function.
9151         */
9152 
9153         /* Shift the Feature start, end and strand in one call. */
9154 
9155         if (ensSliceGetStrand(slice) > 0)
9156             ensFeatureMove(feature,
9157                            start - ensSliceGetStart(slice) + 1,
9158                            end   - ensSliceGetStart(slice) + 1,
9159                            +strand);
9160         else
9161             ensFeatureMove(feature,
9162                            ensSliceGetEnd(slice) - end   + 1,
9163                            ensSliceGetEnd(slice) - start + 1,
9164                            -strand);
9165 
9166         ensFeatureSetSlice(feature, slice);
9167     }
9168 
9169     ajListIterDel(&iter);
9170 
9171     ajListFree(&mrs);
9172 
9173     return ajTrue;
9174 }
9175 
9176 
9177 
9178 
9179 /* @func ensAssemblyexceptionfeatureadaptorFetchAllbySlice ********************
9180 **
9181 ** Fetch all Ensembl Assembly Exception Feature objects via an Ensembl Slice.
9182 **
9183 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
9184 ** Ensembl Assembly Exception Feature Adaptor
9185 ** @param [u] slice [EnsPSlice] Ensembl Slice
9186 ** @param [u] aefs [AjPList]
9187 ** AJAX List of Ensembl Assembly Exception Feature objects
9188 **
9189 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
9190 **
9191 ** @release 6.4.0
9192 ** @@
9193 ******************************************************************************/
9194 
ensAssemblyexceptionfeatureadaptorFetchAllbySlice(EnsPAssemblyexceptionfeatureadaptor aefa,EnsPSlice slice,AjPList aefs)9195 AjBool ensAssemblyexceptionfeatureadaptorFetchAllbySlice(
9196     EnsPAssemblyexceptionfeatureadaptor aefa,
9197     EnsPSlice slice,
9198     AjPList aefs)
9199 {
9200     AjPList css = NULL;
9201 
9202     AjPStr name = NULL;
9203 
9204     EnsPAssemblymapper am         = NULL;
9205     EnsPAssemblymapperadaptor ama = NULL;
9206 
9207     EnsPCoordsystem mcs = NULL;
9208     EnsPCoordsystem scs = NULL;
9209 
9210     EnsPDatabaseadaptor dba = NULL;
9211 
9212     EnsPMetacoordinateadaptor mca = NULL;
9213 
9214     if (!aefa)
9215         return ajFalse;
9216 
9217     if (!slice)
9218         return ajFalse;
9219 
9220     if (!aefs)
9221         return ajFalse;
9222 
9223     /* Return Feature objects from the Slice cache if present. */
9224 
9225     /*
9226     ** FIXME: The Perl API cache uses the Slice name as the key.
9227     ** If Feature objects are requested for a Slice that is based on the same
9228     ** Sequence Region, but has differnt start end coordinates the Feature
9229     ** cache does not work, as the Slice name would be differnt.
9230     ** Therefore, the same set of Feature objects could be cached under
9231     ** different Slice names.
9232     ** Wouldn't it be better to use the Sequence Region identifier as the
9233     ** cache key and do the re-mapping from there?
9234     */
9235 
9236     /* TODO: Implement Slice cache.
9237        my $key= uc($slice->name());
9238     */
9239 
9240     /* TODO: Implement Slice cache.
9241        if (exists($self->{'_aexc_slice_cache'}->{$key})) {
9242        return $self->{'_aexc_slice_cache'}->{$key};
9243        }
9244     */
9245 
9246     ensAssemblyexceptionfeatureadaptorFetchAll(aefa, aefs);
9247 
9248     dba = ensAssemblyexceptionfeatureadaptorGetDatabaseadaptor(aefa);
9249 
9250     mca = ensRegistryGetMetacoordinateadaptor(dba);
9251 
9252     name = ajStrNewC("assembly_exception");
9253 
9254     css = ajListNew();
9255 
9256     ensMetacoordinateadaptorRetrieveAllCoordsystems(mca, name, css);
9257 
9258     ama = ensRegistryGetAssemblymapperadaptor(dba);
9259 
9260     scs = ensSliceGetCoordsystemObject(slice);
9261 
9262     while (ajListPop(css, (void **) &mcs))
9263     {
9264         if (ensCoordsystemMatch(mcs, scs))
9265             am = NULL;
9266         else
9267             ensAssemblymapperadaptorFetchByCoordsystems(ama, mcs, scs, &am);
9268 
9269         /*
9270         ** FIXME: assemblyexceptionfeatureadaptorRemap is completely identical
9271         ** to featureadaptorRemap.
9272         */
9273         assemblyexceptionfeatureadaptorRemap(aefa, aefs, am, slice);
9274 
9275         ensCoordsystemDel(&mcs);
9276     }
9277 
9278     /* TODO: Implement Slice cache.
9279        $self->{'_aexc_slice_cache'}->{$key} =\@ features;
9280     */
9281 
9282     ajListFree(&css);
9283 
9284     ajStrDel(&name);
9285 
9286     return ajTrue;
9287 }
9288 
9289 
9290 
9291 
9292 /* @func ensAssemblyexceptionfeatureadaptorFetchByIdentifier ******************
9293 **
9294 ** Fetch all Ensembl Assembly Exception Feature objects.
9295 **
9296 ** @param [u] aefa [EnsPAssemblyexceptionfeatureadaptor]
9297 ** Ensembl Assembly Exception Feature Adaptor
9298 ** @param [r] identifier [ajuint] SQL database-internal identifier
9299 ** @param [wP] Paef [EnsPAssemblyexceptionfeature*]
9300 ** Ensembl Assembly Exception Feature address
9301 **
9302 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
9303 **
9304 ** @release 6.2.0
9305 ** @@
9306 ******************************************************************************/
9307 
ensAssemblyexceptionfeatureadaptorFetchByIdentifier(EnsPAssemblyexceptionfeatureadaptor aefa,ajuint identifier,EnsPAssemblyexceptionfeature * Paef)9308 AjBool ensAssemblyexceptionfeatureadaptorFetchByIdentifier(
9309     EnsPAssemblyexceptionfeatureadaptor aefa,
9310     ajuint identifier,
9311     EnsPAssemblyexceptionfeature *Paef)
9312 {
9313     AjBool result = AJFALSE;
9314 
9315     if (!aefa)
9316         return ajFalse;
9317 
9318     if (!identifier)
9319         return ajFalse;
9320 
9321     if (!Paef)
9322         return ajFalse;
9323 
9324     *Paef = (EnsPAssemblyexceptionfeature) ajTableFetchmodV(
9325         aefa->CacheByIdentifier,
9326         (const void *) &identifier);
9327 
9328     if (*Paef)
9329     {
9330         ensAssemblyexceptionfeatureNewRef(*Paef);
9331 
9332         return ajTrue;
9333     }
9334 
9335     /* For a cache miss re-query the database. */
9336 
9337     /*
9338     ** TODO: This needs to use the Ensembl Feature Adaptor.
9339     result = ensBaseadaptorFetchByIdentifier(
9340     ensAssemblyexceptionfeatureadaptorGetBaseadaptor(aefa),
9341     identifier,
9342     (void **) Paef);
9343     */
9344 
9345     /*
9346     ** TODO: Implement
9347     assemblyexceptionfeatureadaptorCacheInsert(dta, Pdt);
9348     */
9349 
9350     return result;
9351 }
9352