1 /* @source ensexon ************************************************************
2 **
3 ** Ensembl Exon functions
4 **
5 ** @author Copyright (C) 1999 Ensembl Developers
6 ** @author Copyright (C) 2006 Michael K. Schuster
7 ** @version $Revision: 1.67 $
8 ** @modified 2009 by Alan Bleasby for incorporation into EMBOSS core
9 ** @modified $Date: 2013/02/17 13:02:10 $ 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 "ensalign.h"
34 #include "ensexon.h"
35 #include "enstable.h"
36 #include "enstranscript.h"
37 
38 
39 
40 
41 /* ========================================================================= */
42 /* =============================== constants =============================== */
43 /* ========================================================================= */
44 
45 
46 
47 
48 /* ========================================================================= */
49 /* =========================== global variables ============================ */
50 /* ========================================================================= */
51 
52 
53 
54 
55 /* ========================================================================= */
56 /* ============================= private data ============================== */
57 /* ========================================================================= */
58 
59 
60 
61 
62 /* ========================================================================= */
63 /* =========================== private constants =========================== */
64 /* ========================================================================= */
65 
66 /* @conststatic exonadaptorKTablenames ****************************************
67 **
68 ** Array of Ensembl Exon Adaptor SQL table names
69 **
70 ******************************************************************************/
71 
72 static const char *const exonadaptorKTablenames[] =
73 {
74     "exon",
75     (const char *) NULL
76 };
77 
78 
79 
80 
81 /* @conststatic exonadaptorKColumnnames ***************************************
82 **
83 ** Array of Ensembl Exon Adaptor SQL column names
84 **
85 ******************************************************************************/
86 
87 static const char *const exonadaptorKColumnnames[] =
88 {
89     "exon.exon_id",
90     "exon.seq_region_id",
91     "exon.seq_region_start",
92     "exon.seq_region_end",
93     "exon.seq_region_strand",
94     "exon.phase",
95     "exon.end_phase",
96     "exon.is_current",
97     "exon.is_constitutive",
98     "exon.stable_id",
99     "exon.version",
100     "exon.created_date",
101     "exon.modified_date",
102     (const char *) NULL
103 };
104 
105 
106 
107 
108 /* @conststatic exontranscriptadaptorKTablenames ******************************
109 **
110 ** Array of Ensembl Exon-Transcript Adaptor SQL table names
111 **
112 ******************************************************************************/
113 
114 static const char *const exontranscriptadaptorKTablenames[] =
115 {
116     "exon",
117     "exon_transcript",
118     (const char *) NULL
119 };
120 
121 
122 
123 
124 /* @conststatic exontranscriptadaptorKDefaultcondition ************************
125 **
126 ** Ensembl Exon-Transcript Adaptor SQL SELECT default condition
127 **
128 ******************************************************************************/
129 
130 static const char *exontranscriptadaptorKDefaultcondition =
131     "exon.exon_id = exon_transcript.exon_id";
132 
133 
134 
135 
136 /* @conststatic exontranscriptadaptorKFinalcondition **************************
137 **
138 ** Ensembl Exon-Transcript Adaptor SQL SELECT final condition
139 **
140 ******************************************************************************/
141 
142 static const char *exontranscriptadaptorKFinalcondition =
143     "ORDER BY "
144     "exon_transcript.transcript_id, "
145     "exon_transcript.rank";
146 
147 
148 
149 
150 /* ========================================================================= */
151 /* =========================== private variables =========================== */
152 /* ========================================================================= */
153 
154 
155 
156 
157 /* ========================================================================= */
158 /* =========================== private functions =========================== */
159 /* ========================================================================= */
160 
161 static AjBool exonMergeCoordinates(AjPList mrs);
162 
163 static int listExonCompareEndAscending(
164     const void *item1,
165     const void *item2);
166 
167 static int listExonCompareEndDescending(
168     const void *item1,
169     const void *item2);
170 
171 static int listExonCompareIdentifierAscending(
172     const void *item1,
173     const void *item2);
174 
175 static int listExonCompareStartAscending(
176     const void *item1,
177     const void *item2);
178 
179 static int listExonCompareStartDescending(
180     const void *item1,
181     const void *item2);
182 
183 static AjBool exonadaptorFetchAllbyStatement(
184     EnsPBaseadaptor ba,
185     const AjPStr statement,
186     EnsPAssemblymapper am,
187     EnsPSlice slice,
188     AjPList exons);
189 
190 
191 
192 
193 /* ========================================================================= */
194 /* ======================= All functions by section ======================== */
195 /* ========================================================================= */
196 
197 
198 
199 
200 /* @filesection ensexon *******************************************************
201 **
202 ** @nam1rule ens Function belongs to the Ensembl library
203 **
204 ******************************************************************************/
205 
206 
207 
208 
209 /* @datasection [EnsPExoncoordinates] Ensembl Exon Coordinates ****************
210 **
211 ** @nam2rule Exoncoordinates
212 ** Functions for manipulating Ensembl Exon Coordinates objects
213 **
214 ******************************************************************************/
215 
216 
217 
218 
219 /* @section constructors ******************************************************
220 **
221 ** All constructors return a new Ensembl Exon Coordinates by pointer.
222 ** It is the responsibility of the user to first destroy any previous
223 ** Exon Coordinates. The target pointer does not need to be initialised to
224 ** NULL, but it is good programming practice to do so anyway.
225 **
226 ** @fdata [EnsPExoncoordinates]
227 **
228 ** @nam4rule Cpy Constructor with existing object
229 ** @nam3rule New Constructor
230 ** @nam4rule Ini Constructor with initial values
231 ** @nam4rule NewRef Constructor by incrementing the reference counter
232 **
233 ** @argrule Cpy ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
234 ** @argrule Ini exon [EnsPExon] Ensembl Exon
235 ** @argrule Ini transcript [EnsPTranscript] Ensembl Transcript
236 ** @argrule Ini translation [EnsPTranslation] Ensembl Translation
237 ** @argrule Ref ec [EnsPExoncoordinates] Ensembl Exon Coordinates
238 **
239 ** @valrule * [EnsPExoncoordinates] Ensembl Exon Coordinates or NULL
240 **
241 ** @fcategory new
242 ******************************************************************************/
243 
244 
245 
246 
247 /* @func ensExoncoordinatesNewCpy *********************************************
248 **
249 ** Object-based constructor function, which returns an independent object.
250 **
251 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
252 **
253 ** @return [EnsPExoncoordinates] Ensembl Exon Coordinates or NULL
254 **
255 ** @release 6.5.0
256 ** @@
257 ******************************************************************************/
258 
ensExoncoordinatesNewCpy(const EnsPExoncoordinates ec)259 EnsPExoncoordinates ensExoncoordinatesNewCpy(const EnsPExoncoordinates ec)
260 {
261     EnsPExoncoordinates pthis = NULL;
262 
263     if (!ec)
264         return NULL;
265 
266     AJNEW0(pthis);
267 
268     pthis->TranscriptStart       = ec->TranscriptStart;
269     pthis->TranscriptEnd         = ec->TranscriptEnd;
270     pthis->TranscriptCodingStart = ec->TranscriptCodingStart;
271     pthis->TranscriptCodingEnd   = ec->TranscriptCodingEnd;
272     pthis->SliceCodingStart      = ec->SliceCodingStart;
273     pthis->SliceCodingEnd        = ec->SliceCodingEnd;
274     pthis->Use                   = 1U;
275 
276     return pthis;
277 }
278 
279 
280 
281 
282 /* @func ensExoncoordinatesNewIni *********************************************
283 **
284 ** Ensembl Exon Coordinates constructor with initial values.
285 **
286 ** The function calculates Ensembl Exon coordinates based on an
287 ** Ensembl Transcript and an Ensembl Translation.
288 **
289 ** @cc Bio::EnsEMBL::Exon::coding_region_start
290 ** @cc Bio::EnsEMBL::Exon::coding_region_end
291 ** @cc Bio::EnsEMBL::Exon::cdna_coding_start
292 ** @cc Bio::EnsEMBL::Exon::cdna_coding_end
293 ** @cc Bio::EnsEMBL::Exon::cdna_start
294 ** @cc Bio::EnsEMBL::Exon::cdna_end
295 ** @param [u] exon [EnsPExon] Ensembl Exon
296 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
297 ** @param [uN] translation [EnsPTranslation] Ensembl Translation
298 **
299 ** @return [EnsPExoncoordinates] Ensembl Exon Coordinates or NULL
300 **
301 ** @release 6.4.0
302 ** @@
303 ******************************************************************************/
304 
ensExoncoordinatesNewIni(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation)305 EnsPExoncoordinates ensExoncoordinatesNewIni(EnsPExon exon,
306                                              EnsPTranscript transcript,
307                                              EnsPTranslation translation)
308 {
309     ajint  scstart = 0;  /* Ensembl Slice coding start */
310     ajint  scend   = 0;  /* Ensembl Slice coding end   */
311 
312     ajuint tcstart = 0U; /* Ensembl Transcript coding start */
313     ajuint tcend   = 0U; /* Ensembl Transcript coding end   */
314 
315     AjBool debug = AJFALSE;
316 
317     AjPList mrs = NULL;
318 
319     EnsPExoncoordinates ec = NULL;
320 
321     EnsPFeature feature = NULL;
322 
323     EnsPMapperresult mr = NULL;
324 
325     debug = ajDebugTest("ensExoncoordinatesNewIni");
326 
327     if (debug)
328         ajDebug("ensExoncoordinatesNewIni\n"
329                 "  exon %p\n"
330                 "  transcript %p\n"
331                 "  translation %p\n",
332                 exon,
333                 transcript,
334                 translation);
335 
336     if (!exon)
337         return NULL;
338 
339     if (!transcript)
340         return NULL;
341 
342     AJNEW0(ec);
343 
344     /*
345     ** Calculate the start and end of this Ensembl Exon in
346     ** Ensembl Transcript coordinates.
347     */
348 
349     mrs = ajListNew();
350 
351     ensTranscriptMapperSliceTotranscript(transcript,
352                                          ensFeatureGetStart(exon->Feature),
353                                          ensFeatureGetEnd(exon->Feature),
354                                          ensFeatureGetStrand(exon->Feature),
355                                          mrs);
356 
357     if (!ajListGetLength(mrs))
358     {
359         ajDebug("ensExoncoordinatesNewIni cannot map Ensembl Exon %p from "
360                 "its Slice onto Transcript %p.\n", exon, transcript);
361 
362         ensExonTrace(exon, 1);
363 
364         ensTranscriptTrace(transcript, 1);
365     }
366 
367     ajListPeekFirst(mrs, (void **) &mr);
368 
369     switch (ensMapperresultGetType(mr))
370     {
371         case ensEMapperresultTypeCoordinate:
372 
373             ec->TranscriptStart = ensMapperresultGetCoordinateStart(mr);
374             ec->TranscriptEnd   = ensMapperresultGetCoordinateEnd(mr);
375 
376             if (debug)
377                 ajDebug("ensExoncoordinatesNewIni Exon '%S' "
378                         "Transcript '%S:%d:%d'.\n",
379                         ensExonGetStableidentifier(exon),
380                         ensTranscriptGetStableidentifier(transcript),
381                         ec->TranscriptStart,
382                         ec->TranscriptEnd);
383 
384             break;
385 
386         case ensEMapperresultTypeGap:
387 
388             if (debug)
389             {
390                 ajDebug("ensExoncoordinatesNewIni maps the first part of "
391                         "Ensembl Exon %p into a gap %d:%d for "
392                         "Transcript %p.\n",
393                         exon,
394                         ensMapperresultGetGapStart(mr),
395                         ensMapperresultGetGapEnd(mr),
396                         transcript);
397 
398                 ensExonTrace(exon, 1);
399 
400                 ensTranscriptTrace(transcript, 1);
401             }
402 
403             break;
404 
405         default:
406 
407             ajWarn("ensExoncoordinatesNewIni got an Ensembl Mapper Result of "
408                    "unexpected type %d.", ensMapperresultGetType(mr));
409     }
410 
411     while (ajListPop(mrs, (void **) &mr))
412         ensMapperresultDel(&mr);
413 
414     ajListFree(&mrs);
415 
416     /*
417     ** Calculate the start and end of the coding region of this Ensembl Exon
418     ** in Ensembl Transcript coordinates.
419     */
420 
421     if (!translation)
422         return ec;
423 
424     tcstart = ensTranscriptCalculateTranscriptCodingStart(transcript,
425                                                           translation);
426 
427     tcend   = ensTranscriptCalculateTranscriptCodingEnd(transcript,
428                                                         translation);
429 
430     if (debug)
431         ajDebug("ensExoncoordinatesNewIni Transcript Coding %d:%d\n",
432                 tcstart, tcend);
433 
434     if (!tcstart)
435     {
436         /* This is a non-coding Transcript. */
437 
438         ec->TranscriptCodingStart = 0;
439         ec->TranscriptCodingEnd   = 0;
440     }
441     else
442     {
443         if (tcstart < ec->TranscriptStart)
444         {
445             /* The coding region starts up-stream of this Exon ... */
446 
447             if (tcend < ec->TranscriptStart)
448             {
449                 /* ... and also ends up-stream of this Exon. */
450 
451                 ec->TranscriptCodingStart = 0;
452                 ec->TranscriptCodingEnd   = 0;
453             }
454             else
455             {
456                 /* ... and does not end up-stream of this Exon, but ... */
457 
458                 ec->TranscriptCodingStart = ec->TranscriptStart;
459 
460                 if (tcend < ec->TranscriptEnd)
461                 {
462                     /* ... ends in this Exon. */
463 
464                     ec->TranscriptCodingEnd = tcend;
465                 }
466                 else
467                 {
468                     /* ... ends down-stream of this Exon. */
469 
470                     ec->TranscriptCodingEnd = ec->TranscriptEnd;
471                 }
472             }
473         }
474         else
475         {
476             /*
477             ** The coding region starts either within or down-stream of
478             ** this Exon.
479             */
480 
481             if (tcstart <= ec->TranscriptEnd)
482             {
483                 /* The coding region starts within this Exon ... */
484 
485                 ec->TranscriptCodingStart = tcstart;
486 
487                 if (tcend < ec->TranscriptEnd)
488                 {
489                     /* ... and also ends within this Exon. */
490 
491                     ec->TranscriptCodingEnd = tcend;
492                 }
493                 else
494                 {
495                     /* ... and ends down-stream of this Exon. */
496 
497                     ec->TranscriptCodingEnd = ec->TranscriptEnd;
498                 }
499             }
500             else
501             {
502                 /*
503                 ** The coding region starts and ends down-stream
504                 ** of this Exon.
505                 */
506 
507                 ec->TranscriptCodingStart = 0;
508                 ec->TranscriptCodingEnd   = 0;
509             }
510         }
511     }
512 
513     /*
514     ** Calculate the start and end of the coding region of this Ensembl Exon
515     ** in Ensembl Slice coordinates.
516     */
517 
518     scstart = ensTranscriptCalculateSliceCodingStart(transcript, translation);
519     scend   = ensTranscriptCalculateSliceCodingEnd(transcript, translation);
520 
521     if (!scstart)
522     {
523         /* This is a non-coding Transcript. */
524 
525         ec->SliceCodingStart = 0;
526         ec->SliceCodingEnd   = 0;
527     }
528     else
529     {
530         feature = ensExonGetFeature(exon);
531 
532         if (scstart < ensFeatureGetStart(feature))
533         {
534             /* The coding region starts up-stream of this Exon ... */
535 
536             if (scend < ensFeatureGetStart(feature))
537             {
538                 /* ... and also ends up-stream of this Exon. */
539 
540                 ec->SliceCodingStart = 0;
541                 ec->SliceCodingEnd   = 0;
542             }
543             else
544             {
545                 /* ... and does not end up-stream of this Exon, but ... */
546 
547                 ec->SliceCodingStart = ensFeatureGetStart(feature);
548 
549                 if (scend < ensFeatureGetEnd(feature))
550                 {
551                     /* ... ends in this Exon. */
552 
553                     ec->SliceCodingEnd = scend;
554                 }
555 
556                 else
557                 {
558                     /* ... ends down-stream of this Exon. */
559 
560                     ec->SliceCodingEnd = ensFeatureGetEnd(feature);
561                 }
562             }
563         }
564         else
565         {
566             /*
567             ** The coding region starts either within or down-stream of
568             ** this Exon.
569             */
570 
571             if (scstart <= ensFeatureGetEnd(feature))
572             {
573                 /* The coding region starts within this Exon ... */
574 
575                 ec->SliceCodingStart = scstart;
576 
577                 if (scend < ensFeatureGetEnd(feature))
578                 {
579                     /* ... and also ends within this Exon . */
580 
581                     ec->SliceCodingEnd = scend;
582                 }
583                 else
584                 {
585                     /* ... and ends down-stream of this Exon. */
586 
587                     ec->SliceCodingEnd = ensFeatureGetEnd(feature);
588                 }
589             }
590             else
591             {
592                 /*
593                 ** The coding region starts and ends down-stream
594                 ** of this Exon.
595                 */
596 
597                 ec->SliceCodingStart = 0;
598                 ec->SliceCodingEnd   = 0;
599             }
600         }
601     }
602 
603     return ec;
604 }
605 
606 
607 
608 
609 /* @func ensExoncoordinatesNewRef *********************************************
610 **
611 ** Ensembl Object referencing function, which returns a pointer to the
612 ** Ensembl Object passed in and increases its reference count.
613 **
614 ** @param [u] ec [EnsPExoncoordinates] Ensembl Exon Coordinates
615 **
616 ** @return [EnsPExoncoordinates] Ensembl Exon Coordinates or NULL
617 **
618 ** @release 6.5.0
619 ** @@
620 ******************************************************************************/
621 
ensExoncoordinatesNewRef(EnsPExoncoordinates ec)622 EnsPExoncoordinates ensExoncoordinatesNewRef(EnsPExoncoordinates ec)
623 {
624     if (!ec)
625         return NULL;
626 
627     ec->Use++;
628 
629     return ec;
630 }
631 
632 
633 
634 
635 /* @section destructors *******************************************************
636 **
637 ** Destruction destroys all internal data structures and frees the memory
638 ** allocated for an Ensembl Exon Coordinates object.
639 **
640 ** @fdata [EnsPExoncoordinates]
641 **
642 ** @nam3rule Del Destroy (free) an Ensembl Exon Coordinates
643 **
644 ** @argrule * Pec [EnsPExoncoordinates*] Ensembl Exon Coordinates address
645 **
646 ** @valrule * [void]
647 **
648 ** @fcategory delete
649 ******************************************************************************/
650 
651 
652 
653 
654 /* @func ensExoncoordinatesDel ************************************************
655 **
656 ** Default destructor for an Exon Coordinates object.
657 **
658 ** @param [d] Pec [EnsPExoncoordinates*] Ensembl Exon Coordinates address
659 **
660 ** @return [void]
661 **
662 ** @release 6.5.0
663 ** @@
664 ******************************************************************************/
665 
ensExoncoordinatesDel(EnsPExoncoordinates * Pec)666 void ensExoncoordinatesDel(EnsPExoncoordinates *Pec)
667 {
668     ajMemFree((void **) Pec);
669 
670     return;
671 }
672 
673 
674 
675 
676 /* @section member retrieval **************************************************
677 **
678 ** Functions for returning members of an Ensembl Exon Coordinates object.
679 **
680 ** @fdata [EnsPExoncoordinates]
681 **
682 ** @nam3rule Get Return Ensembl Exon Coordinates attribute(s)
683 ** @nam4rule Slice      Calculate Ensembl Exon coordinates relative to an
684 **                      Ensembl Slice
685 ** @nam5rule Coding Calculate Ensembl Exon coding coordinates
686 ** @nam6rule End    Calculate the Ensembl Exon coding start coordinate
687 ** @nam6rule Start  Calculate the Ensembl Exon coding end coordinate
688 ** @nam4rule Transcript Calculate Ensembl Exon coordinates relative to an
689 **                      Ensembl Transcript
690 ** @nam5rule Coding Calculate Ensembl Exon coding coordinates
691 ** @nam6rule End    Calculate the Ensembl Exon coding start coordinate
692 ** @nam6rule Start  Calculate the Ensembl Exon coding end coordinate
693 ** @nam5rule End    Calculate the Ensembl Exon end coordinate
694 ** @nam5rule Start  Calculate the Ensembl Exon start coordinate
695 **
696 ** @argrule * ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
697 **
698 ** @valrule SliceCodingEnd [ajint] End coordinate or 0
699 ** @valrule SliceCodingStart [ajint] Start coordinate or 0
700 ** @valrule TranscriptCodingEnd [ajuint] End coordinate or 0U
701 ** @valrule TranscriptCodingStart [ajuint] Start coordinate or 0U
702 ** @valrule TranscriptEnd [ajuint] End coordinate or 0U
703 ** @valrule TranscriptStart [ajuint] Start coordinate or 0U
704 **
705 ** @fcategory use
706 ******************************************************************************/
707 
708 
709 
710 
711 /* @func ensExoncoordinatesGetSliceCodingEnd **********************************
712 **
713 ** Get the end coordinate of the coding region of an Ensembl Exon
714 ** relaive to an Ensembl Slice.
715 **
716 ** @cc Bio::EnsEMBL::Exon::coding_region_end
717 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
718 **
719 ** @return [ajint] Coding end coordinate or 0
720 **
721 ** @release 6.5.0
722 ** @@
723 ******************************************************************************/
724 
ensExoncoordinatesGetSliceCodingEnd(const EnsPExoncoordinates ec)725 ajint ensExoncoordinatesGetSliceCodingEnd(
726     const EnsPExoncoordinates ec)
727 {
728     return (ec) ? ec->SliceCodingEnd : 0;
729 }
730 
731 
732 
733 
734 /* @func ensExoncoordinatesGetSliceCodingStart ********************************
735 **
736 ** Get the start coordinate of the coding region of an Ensembl Exon
737 ** relaive to an Ensembl Slice.
738 **
739 ** @cc Bio::EnsEMBL::Exon::coding_region_start
740 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
741 **
742 ** @return [ajint] Coding start coordinate or 0
743 **
744 ** @release 6.5.0
745 ** @@
746 ******************************************************************************/
747 
ensExoncoordinatesGetSliceCodingStart(const EnsPExoncoordinates ec)748 ajint ensExoncoordinatesGetSliceCodingStart(
749     const EnsPExoncoordinates ec)
750 {
751     return (ec) ? ec->SliceCodingStart : 0;
752 }
753 
754 
755 
756 
757 /* @func ensExoncoordinatesGetTranscriptCodingEnd *****************************
758 **
759 ** Get the end coordinate of the coding region of an Ensembl Exon
760 ** relative to an Ensembl Transcript.
761 **
762 ** @cc Bio::EnsEMBL::Exon::cdna_coding_end
763 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
764 **
765 ** @return [ajuint] Coding end coordinate or 0U
766 **
767 ** @release 6.5.0
768 ** @@
769 ******************************************************************************/
770 
ensExoncoordinatesGetTranscriptCodingEnd(const EnsPExoncoordinates ec)771 ajuint ensExoncoordinatesGetTranscriptCodingEnd(
772     const EnsPExoncoordinates ec)
773 {
774     return (ec) ? ec->TranscriptCodingEnd : 0U;
775 }
776 
777 
778 
779 
780 /* @func ensExoncoordinatesGetTranscriptCodingStart ***************************
781 **
782 ** Get the start coordinate of the coding region of an Ensembl Exon
783 ** relative to an Ensembl Transcript.
784 **
785 ** @cc Bio::EnsEMBL::Exon::cdna_coding_start
786 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
787 **
788 ** @return [ajuint] Coding start coordinate or 0U
789 **
790 ** @release 6.5.0
791 ** @@
792 ******************************************************************************/
793 
ensExoncoordinatesGetTranscriptCodingStart(const EnsPExoncoordinates ec)794 ajuint ensExoncoordinatesGetTranscriptCodingStart(
795     const EnsPExoncoordinates ec)
796 {
797     return (ec) ? ec->TranscriptCodingStart : 0U;
798 }
799 
800 
801 
802 
803 /* @func ensExoncoordinatesGetTranscriptEnd ***********************************
804 **
805 ** Get the end coordinate of an Ensembl Exon relative to an
806 ** Ensembl Transcript.
807 **
808 ** @cc Bio::EnsEMBL::Exon::cdna_end
809 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
810 **
811 ** @return [ajuint] End coordinate or 0U
812 **
813 ** @release 6.5.0
814 ** @@
815 ******************************************************************************/
816 
ensExoncoordinatesGetTranscriptEnd(const EnsPExoncoordinates ec)817 ajuint ensExoncoordinatesGetTranscriptEnd(
818     const EnsPExoncoordinates ec)
819 {
820     return (ec) ? ec->TranscriptEnd : 0U;
821 }
822 
823 
824 
825 
826 /* @func ensExoncoordinatesGetTranscriptStart *********************************
827 **
828 ** Get the start coordinate of an Ensembl Exon relative to an
829 ** Ensembl Transcript.
830 **
831 ** @cc Bio::EnsEMBL::Exon::cdna_start
832 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
833 **
834 ** @return [ajuint] Start coordinate or 0U
835 **
836 ** @release 6.5.0
837 ** @@
838 ******************************************************************************/
839 
ensExoncoordinatesGetTranscriptStart(const EnsPExoncoordinates ec)840 ajuint ensExoncoordinatesGetTranscriptStart(
841     const EnsPExoncoordinates ec)
842 {
843     return (ec) ? ec->TranscriptStart : 0U;
844 }
845 
846 
847 
848 
849 /* @section debugging *********************************************************
850 **
851 ** Functions for reporting of an Ensembl Exon Coordinates object.
852 **
853 ** @fdata [EnsPExoncoordinates]
854 **
855 ** @nam3rule Trace Report Ensembl Exon Coordinates members to debug file
856 **
857 ** @argrule Trace ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
858 ** @argrule Trace level [ajuint] Indentation level
859 **
860 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
861 **
862 ** @fcategory misc
863 ******************************************************************************/
864 
865 
866 
867 
868 /* @func ensExoncoordinatesTrace **********************************************
869 **
870 ** Trace an Ensembl Exon Coordinates.
871 **
872 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
873 ** @param [r] level [ajuint] Indentation level
874 **
875 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
876 **
877 ** @release 6.5.0
878 ** @@
879 ******************************************************************************/
880 
ensExoncoordinatesTrace(const EnsPExoncoordinates ec,ajuint level)881 AjBool ensExoncoordinatesTrace(const EnsPExoncoordinates ec, ajuint level)
882 {
883     AjPStr indent = NULL;
884 
885     if (!ec)
886         return ajFalse;
887 
888     indent = ajStrNew();
889 
890     ajStrAppendCountK(&indent, ' ', level * 2);
891 
892     ajDebug("%ensExoncoordinatesTrace %p\n"
893             "%S  TranscriptStart %u\n"
894             "%S  TranscriptEnd %u\n"
895             "%S  TranscriptCodingStart %u\n"
896             "%S  TranscriptCodingEnd %u\n"
897             "%S  SliceCodingStart %d\n"
898             "%S  SliceCodingEnd %d\n"
899             "%S  Use %u\n",
900             indent, ec,
901             indent, ec->TranscriptStart,
902             indent, ec->TranscriptEnd,
903             indent, ec->TranscriptCodingStart,
904             indent, ec->TranscriptCodingEnd,
905             indent, ec->SliceCodingStart,
906             indent, ec->SliceCodingEnd,
907             indent, ec->Use);
908 
909     ajStrDel(&indent);
910 
911     return ajTrue;
912 }
913 
914 
915 
916 
917 /* @section calculate *********************************************************
918 **
919 ** Functions for calculating information from an Ensembl Exon object.
920 **
921 ** @fdata [EnsPExoncoordinates]
922 **
923 ** @nam3rule Calculate Calculate Ensembl Exon information
924 ** @nam4rule Memsize Calculate the memory size in bytes
925 **
926 ** @argrule Memsize ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
927 **
928 ** @valrule Memsize [size_t] Memory size in bytes or 0
929 **
930 ** @fcategory misc
931 ******************************************************************************/
932 
933 
934 
935 
936 /* @func ensExoncoordinatesCalculateMemsize ***********************************
937 **
938 ** Calculate the memory size in bytes of an Ensembl Exon Coordinates.
939 **
940 ** @param [r] ec [const EnsPExoncoordinates] Ensembl Exon Coordinates
941 **
942 ** @return [size_t] Memory size in bytes or 0
943 **
944 ** @release 6.4.0
945 ** @@
946 ******************************************************************************/
947 
ensExoncoordinatesCalculateMemsize(const EnsPExoncoordinates ec)948 size_t ensExoncoordinatesCalculateMemsize(const EnsPExoncoordinates ec)
949 {
950     size_t size = 0;
951 
952     if (!ec)
953         return 0;
954 
955     size += sizeof (EnsOExoncoordinates);
956 
957     return size;
958 }
959 
960 
961 
962 
963 /* @datasection [EnsPExon] Ensembl Exon ***************************************
964 **
965 ** @nam2rule Exon Functions for manipulating Ensembl Exon objects
966 **
967 ** @cc Bio::EnsEMBL::Exon
968 ** @cc CVS Revision: 1.185
969 ** @cc CVS Tag: branch-ensembl-68
970 **
971 ******************************************************************************/
972 
973 
974 
975 
976 /* @section constructors ******************************************************
977 **
978 ** All constructors return a new Ensembl Exon by pointer.
979 ** It is the responsibility of the user to first destroy any previous
980 ** Exon. The target pointer does not need to be initialised to
981 ** NULL, but it is good programming practice to do so anyway.
982 **
983 ** @fdata [EnsPExon]
984 **
985 ** @nam4rule Cpy Constructor with existing object
986 ** @nam3rule New Constructor
987 ** @nam4rule Ini Constructor with initial values
988 ** @nam4rule NewRef Constructor by incrementing the reference counter
989 **
990 ** @argrule Cpy exon [const EnsPExon] Ensembl Exon
991 ** @argrule Ini ea [EnsPExonadaptor] Ensembl Exon Adaptor
992 ** @argrule Ini identifier [ajuint] SQL database-internal identifier
993 ** @argrule Ini feature [EnsPFeature] Ensembl Feature
994 ** @argrule Ini sphase [ajint] Start phase of Translation
995 ** @argrule Ini ephase [ajint] End phase of Translation
996 ** @argrule Ini current [AjBool] Current attribute
997 ** @argrule Ini constitutive [AjBool] Constitutive attribute
998 ** @argrule Ini stableid [AjPStr] Stable identifier
999 ** @argrule Ini version [ajuint] Version
1000 ** @argrule Ini cdate [AjPStr] Creation date
1001 ** @argrule Ini mdate [AjPStr] Modification date
1002 ** @argrule Ref exon [EnsPExon] Ensembl Exon
1003 **
1004 ** @valrule * [EnsPExon] Ensembl Exon or NULL
1005 **
1006 ** @fcategory new
1007 ******************************************************************************/
1008 
1009 
1010 
1011 
1012 /* @func ensExonNewCpy ********************************************************
1013 **
1014 ** Object-based constructor function, which returns an independent object.
1015 **
1016 ** @param [r] exon [const EnsPExon] Ensembl Exon
1017 **
1018 ** @return [EnsPExon] Ensembl Exon or NULL
1019 **
1020 ** @release 6.4.0
1021 ** @@
1022 ******************************************************************************/
1023 
ensExonNewCpy(const EnsPExon exon)1024 EnsPExon ensExonNewCpy(const EnsPExon exon)
1025 {
1026     AjIList iter = NULL;
1027 
1028     EnsPBasealignfeature baf = NULL;
1029 
1030     EnsPExon pthis = NULL;
1031 
1032     if (!exon)
1033         return NULL;
1034 
1035     AJNEW0(pthis);
1036 
1037     pthis->Use          = 1U;
1038     pthis->Identifier   = exon->Identifier;
1039     pthis->Adaptor      = exon->Adaptor;
1040     pthis->Feature      = ensFeatureNewRef(exon->Feature);
1041     pthis->PhaseStart   = exon->PhaseStart;
1042     pthis->PhaseEnd     = exon->PhaseEnd;
1043     pthis->Current      = exon->Current;
1044     pthis->Constitutive = exon->Constitutive;
1045 
1046     if (exon->Stableidentifier)
1047         pthis->Stableidentifier = ajStrNewRef(exon->Stableidentifier);
1048 
1049     pthis->Version = exon->Version;
1050 
1051     if (exon->DateCreation)
1052         pthis->DateCreation = ajStrNewRef(exon->DateCreation);
1053 
1054     if (exon->DateModification)
1055         pthis->DateModification = ajStrNewRef(exon->DateModification);
1056 
1057     if (exon->SequenceCache)
1058         pthis->SequenceCache = ajStrNewRef(exon->SequenceCache);
1059 
1060     /*
1061     ** NOTE: Copy the AJAX List of supporting
1062     ** Ensembl Base Align Feature objects.
1063     */
1064 
1065     if (exon->Supportingfeatures &&
1066         ajListGetLength(exon->Supportingfeatures))
1067     {
1068         pthis->Supportingfeatures = ajListNew();
1069 
1070         iter = ajListIterNew(exon->Supportingfeatures);
1071 
1072         while (!ajListIterDone(iter))
1073         {
1074             baf = (EnsPBasealignfeature) ajListIterGet(iter);
1075 
1076             ajListPushAppend(pthis->Supportingfeatures,
1077                              (void *) ensBasealignfeatureNewRef(baf));
1078         }
1079 
1080         ajListIterDel(&iter);
1081     }
1082 
1083     return pthis;
1084 }
1085 
1086 
1087 
1088 
1089 /* @func ensExonNewIni ********************************************************
1090 **
1091 ** Ensembl Exon constructor with initial values.
1092 **
1093 ** @cc Bio::EnsEMBL::Storable::new
1094 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
1095 ** @param [r] identifier [ajuint] SQL database-internal identifier
1096 ** @cc Bio::EnsEMBL::Feature::new
1097 ** @param [u] feature [EnsPFeature] Ensembl Feature
1098 ** @cc Bio::EnsEMBL::Exon::new
1099 ** @param [r] sphase [ajint] Start phase of Translation
1100 ** @param [r] ephase [ajint] End phase of Translation
1101 ** @param [r] current [AjBool] Current attribute
1102 ** @param [r] constitutive [AjBool] Constitutive attribute
1103 ** @param [u] stableid [AjPStr] Stable identifier
1104 ** @param [r] version [ajuint] Version
1105 ** @param [u] cdate [AjPStr] Creation date
1106 ** @param [u] mdate [AjPStr] Modification date
1107 **
1108 ** @return [EnsPExon] Ensembl Exon or NULL
1109 **
1110 ** @release 6.4.0
1111 ** @@
1112 ******************************************************************************/
1113 
ensExonNewIni(EnsPExonadaptor ea,ajuint identifier,EnsPFeature feature,ajint sphase,ajint ephase,AjBool current,AjBool constitutive,AjPStr stableid,ajuint version,AjPStr cdate,AjPStr mdate)1114 EnsPExon ensExonNewIni(EnsPExonadaptor ea,
1115                        ajuint identifier,
1116                        EnsPFeature feature,
1117                        ajint sphase,
1118                        ajint ephase,
1119                        AjBool current,
1120                        AjBool constitutive,
1121                        AjPStr stableid,
1122                        ajuint version,
1123                        AjPStr cdate,
1124                        AjPStr mdate)
1125 {
1126     EnsPExon exon = NULL;
1127 
1128     if (ajDebugTest("ensExonNewIni"))
1129     {
1130         ajDebug("ensExonNewIni\n"
1131                 "  ea %p\n"
1132                 "  identifier %u\n"
1133                 "  feature %p\n"
1134                 "  sphase %d\n"
1135                 "  ephase %d\n"
1136                 "  current '%B'\n"
1137                 "  constitutive '%B'\n"
1138                 "  stableid '%S'\n"
1139                 "  version %u\n"
1140                 "  cdate '%S'\n"
1141                 "  mdate '%S'\n",
1142                 ea,
1143                 identifier,
1144                 feature,
1145                 sphase,
1146                 ephase,
1147                 current,
1148                 constitutive,
1149                 stableid,
1150                 version,
1151                 cdate,
1152                 mdate);
1153 
1154         ensFeatureTrace(feature, 1);
1155     }
1156 
1157     if (!feature)
1158         return NULL;
1159 
1160     if ((sphase < -1) || (sphase > 2))
1161     {
1162         ajDebug("ensExonNewIni start phase must be 0, 1, 2 for coding regions "
1163                 "or -1 for non-coding regions, not %d.\n", sphase);
1164 
1165         return NULL;
1166     }
1167 
1168     if ((ephase < -1) || (ephase > 2))
1169     {
1170         ajDebug("ensExonNewIni end phase must be 0, 1, 2 for coding regions "
1171                 "or -1 for non-coding regions, not %d.\n", ephase);
1172 
1173         return NULL;
1174     }
1175 
1176     AJNEW0(exon);
1177 
1178     exon->Use          = 1U;
1179     exon->Identifier   = identifier;
1180     exon->Adaptor      = ea;
1181     exon->Feature      = ensFeatureNewRef(feature);
1182     exon->PhaseStart   = sphase;
1183     exon->PhaseEnd     = ephase;
1184     exon->Current      = current;
1185     exon->Constitutive = constitutive;
1186 
1187     if (stableid)
1188         exon->Stableidentifier = ajStrNewRef(stableid);
1189 
1190     exon->Version = version;
1191 
1192     if (cdate)
1193         exon->DateCreation = ajStrNewRef(cdate);
1194 
1195     if (mdate)
1196         exon->DateModification = ajStrNewRef(mdate);
1197 
1198     exon->SequenceCache      = NULL;
1199     exon->Supportingfeatures = NULL;
1200 
1201     return exon;
1202 }
1203 
1204 
1205 
1206 
1207 /* @func ensExonNewRef ********************************************************
1208 **
1209 ** Ensembl Object referencing function, which returns a pointer to the
1210 ** Ensembl Object passed in and increases its reference count.
1211 **
1212 ** @param [u] exon [EnsPExon] Ensembl Exon
1213 **
1214 ** @return [EnsPExon] Ensembl Exon or NULL
1215 **
1216 ** @release 6.2.0
1217 ** @@
1218 ******************************************************************************/
1219 
ensExonNewRef(EnsPExon exon)1220 EnsPExon ensExonNewRef(EnsPExon exon)
1221 {
1222     if (!exon)
1223         return NULL;
1224 
1225     exon->Use++;
1226 
1227     return exon;
1228 }
1229 
1230 
1231 
1232 
1233 /* @section destructors *******************************************************
1234 **
1235 ** Destruction destroys all internal data structures and frees the memory
1236 ** allocated for an Ensembl Exon object.
1237 **
1238 ** @fdata [EnsPExon]
1239 **
1240 ** @nam3rule Del Destroy (free) an Ensembl Exon
1241 **
1242 ** @argrule * Pexon [EnsPExon*] Ensembl Exon address
1243 **
1244 ** @valrule * [void]
1245 **
1246 ** @fcategory delete
1247 ******************************************************************************/
1248 
1249 
1250 
1251 
1252 /* @func ensExonDel ***********************************************************
1253 **
1254 ** Default destructor for an Ensembl Exon.
1255 **
1256 ** @param [d] Pexon [EnsPExon*] Ensembl Exon address
1257 **
1258 ** @return [void]
1259 **
1260 ** @release 6.2.0
1261 ** @@
1262 ******************************************************************************/
1263 
ensExonDel(EnsPExon * Pexon)1264 void ensExonDel(EnsPExon *Pexon)
1265 {
1266     EnsPBasealignfeature baf = NULL;
1267 
1268     EnsPExon pthis = NULL;
1269 
1270     if (!Pexon)
1271         return;
1272 
1273 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
1274     if (ajDebugTest("ensExonDel"))
1275     {
1276         ajDebug("ensExonDel\n"
1277                 "  *Pexon %p\n",
1278                 *Pexon);
1279 
1280         ensExonTrace(*Pexon, 1);
1281     }
1282 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
1283 
1284     if (!(pthis = *Pexon) || --pthis->Use)
1285     {
1286         *Pexon = NULL;
1287 
1288         return;
1289     }
1290 
1291     ensFeatureDel(&pthis->Feature);
1292 
1293     ajStrDel(&pthis->Stableidentifier);
1294     ajStrDel(&pthis->DateCreation);
1295     ajStrDel(&pthis->DateModification);
1296     ajStrDel(&pthis->SequenceCache);
1297 
1298     /*
1299     ** Clear and delete the AJAX List of supporting
1300     ** Ensembl Base Align Feature objects.
1301     */
1302 
1303     while (ajListPop(pthis->Supportingfeatures, (void **) &baf))
1304         ensBasealignfeatureDel(&baf);
1305 
1306     ajListFree(&pthis->Supportingfeatures);
1307 
1308     ajMemFree((void **) Pexon);
1309 
1310     return;
1311 }
1312 
1313 
1314 
1315 
1316 /* @section member retrieval **************************************************
1317 **
1318 ** Functions for returning members of an Ensembl Exon object.
1319 **
1320 ** @fdata [EnsPExon]
1321 **
1322 ** @nam3rule Get Return Ensembl Exon attribute(s)
1323 ** @nam4rule Adaptor Return the Ensembl Exon Adaptor
1324 ** @nam4rule Constitutive Return the constitutive flag
1325 ** @nam4rule Current Return the current flag
1326 ** @nam4rule Date Return a date
1327 ** @nam5rule Creation Return the date of creation
1328 ** @nam5rule Modification Return the date of modification
1329 ** @nam4rule Feature Return the Ensembl Feature
1330 ** @nam4rule Identifier Return the SQL database-internal identifier
1331 ** @nam4rule Phase Return a phase
1332 ** @nam5rule End Return the phase at end
1333 ** @nam5rule Start Return the phase at start
1334 ** @nam4rule Stableidentifier Return the stable identifier
1335 ** @nam4rule Version Return the version
1336 **
1337 ** @argrule * exon [const EnsPExon] Ensembl Exon
1338 **
1339 ** @valrule Adaptor [EnsPExonadaptor] Ensembl Exon Adaptor or NULL
1340 ** @valrule Constitutive [AjBool] Constitutive attribute or ajFalse
1341 ** @valrule Current [AjBool] Current attribute or ajFalse
1342 ** @valrule DateCreation [AjPStr] Creation date or NULL
1343 ** @valrule DateModification [AjPStr] Modification date or NULL
1344 ** @valrule Feature [EnsPFeature] Ensembl Feature or NULL
1345 ** @valrule Identifier [ajuint] SQL database-internal identifier or 0U
1346 ** @valrule PhaseEnd [ajint] Phase at end or 0
1347 ** @valrule PhaseStart [ajint] Phase at start or 0
1348 ** @valrule Stableidentifier [AjPStr] Stable identifier or NULL
1349 ** @valrule Version [ajuint] Version or 0U
1350 **
1351 ** @fcategory use
1352 ******************************************************************************/
1353 
1354 
1355 
1356 
1357 /* @func ensExonGetAdaptor ****************************************************
1358 **
1359 ** Get the Ensembl Exon Adaptor member of an Ensembl Exon.
1360 **
1361 ** @cc Bio::EnsEMBL::Storable::adaptor
1362 ** @param [r] exon [const EnsPExon] Ensembl Exon
1363 **
1364 ** @return [EnsPExonadaptor] Ensembl Exon Adaptor or NULL
1365 **
1366 ** @release 6.2.0
1367 ** @@
1368 ******************************************************************************/
1369 
ensExonGetAdaptor(const EnsPExon exon)1370 EnsPExonadaptor ensExonGetAdaptor(const EnsPExon exon)
1371 {
1372     return (exon) ? exon->Adaptor : NULL;
1373 }
1374 
1375 
1376 
1377 
1378 /* @func ensExonGetConstitutive ***********************************************
1379 **
1380 ** Get the constitutive flag member of an Ensembl Exon.
1381 **
1382 ** @cc Bio::EnsEMBL::Exon::is_constitutive
1383 ** @param [r] exon [const EnsPExon] Ensembl Exon
1384 **
1385 ** @return [AjBool] ajTrue if this Exon is constitutive
1386 **
1387 ** @release 6.2.0
1388 ** @@
1389 ******************************************************************************/
1390 
ensExonGetConstitutive(const EnsPExon exon)1391 AjBool ensExonGetConstitutive(const EnsPExon exon)
1392 {
1393     return (exon) ? exon->Constitutive : ajFalse;
1394 }
1395 
1396 
1397 
1398 
1399 /* @func ensExonGetCurrent ****************************************************
1400 **
1401 ** Get the current flag member of an Ensembl Exon.
1402 **
1403 ** @cc Bio::EnsEMBL::Exon::is_current
1404 ** @param [r] exon [const EnsPExon] Ensembl Exon
1405 **
1406 ** @return [AjBool] ajTrue if this Exon reflects the current state of
1407 **                  annotation
1408 **
1409 ** @release 6.2.0
1410 ** @@
1411 ******************************************************************************/
1412 
ensExonGetCurrent(const EnsPExon exon)1413 AjBool ensExonGetCurrent(const EnsPExon exon)
1414 {
1415     return (exon) ? exon->Current : ajFalse;
1416 }
1417 
1418 
1419 
1420 
1421 /* @func ensExonGetDateCreation ***********************************************
1422 **
1423 ** Get the date of creation member of an Ensembl Exon.
1424 **
1425 ** @cc Bio::EnsEMBL::Exon::created_date
1426 ** @param [r] exon [const EnsPExon] Ensembl Exon
1427 **
1428 ** @return [AjPStr] Creation date or NULL
1429 **
1430 ** @release 6.4.0
1431 ** @@
1432 ******************************************************************************/
1433 
ensExonGetDateCreation(const EnsPExon exon)1434 AjPStr ensExonGetDateCreation(const EnsPExon exon)
1435 {
1436     return (exon) ? exon->DateCreation : NULL;
1437 }
1438 
1439 
1440 
1441 
1442 /* @func ensExonGetDateModification *******************************************
1443 **
1444 ** Get the date of modification member of an Ensembl Exon.
1445 **
1446 ** @cc Bio::EnsEMBL::Exon::modified_date
1447 ** @param [r] exon [const EnsPExon] Ensembl Exon
1448 **
1449 ** @return [AjPStr] Modification date or NULL
1450 **
1451 ** @release 6.4.0
1452 ** @@
1453 ******************************************************************************/
1454 
ensExonGetDateModification(const EnsPExon exon)1455 AjPStr ensExonGetDateModification(const EnsPExon exon)
1456 {
1457     return (exon) ? exon->DateModification : NULL;
1458 }
1459 
1460 
1461 
1462 
1463 /* @func ensExonGetFeature ****************************************************
1464 **
1465 ** Get the Ensembl Feature member of an Ensembl Exon.
1466 **
1467 ** @cc Bio::EnsEMBL::Exon::slice
1468 ** @cc Bio::EnsEMBL::Exon::start
1469 ** @cc Bio::EnsEMBL::Exon::end
1470 ** @cc Bio::EnsEMBL::Exon::strand
1471 ** @param [r] exon [const EnsPExon] Ensembl Exon
1472 **
1473 ** @return [EnsPFeature] Ensembl Feature or NULL
1474 **
1475 ** @release 6.2.0
1476 ** @@
1477 ******************************************************************************/
1478 
ensExonGetFeature(const EnsPExon exon)1479 EnsPFeature ensExonGetFeature(const EnsPExon exon)
1480 {
1481     return (exon) ? exon->Feature : NULL;
1482 }
1483 
1484 
1485 
1486 
1487 /* @func ensExonGetIdentifier *************************************************
1488 **
1489 ** Get the SQL database-internal identifier member of an Ensembl Exon.
1490 **
1491 ** @cc Bio::EnsEMBL::Storable::dbID
1492 ** @param [r] exon [const EnsPExon] Ensembl Exon
1493 **
1494 ** @return [ajuint] SQL database-internal identifier or 0U
1495 **
1496 ** @release 6.2.0
1497 ** @@
1498 ******************************************************************************/
1499 
ensExonGetIdentifier(const EnsPExon exon)1500 ajuint ensExonGetIdentifier(const EnsPExon exon)
1501 {
1502     return (exon) ? exon->Identifier : 0U;
1503 }
1504 
1505 
1506 
1507 
1508 /* @func ensExonGetPhaseEnd ***************************************************
1509 **
1510 ** Get the phase at end member of an Ensembl Exon.
1511 **
1512 ** @cc Bio::EnsEMBL::Exon::end_phase
1513 ** @param [r] exon [const EnsPExon] Ensembl Exon
1514 **
1515 ** @return [ajint] End phase or 0
1516 **
1517 ** @release 6.4.0
1518 ** @@
1519 ******************************************************************************/
1520 
ensExonGetPhaseEnd(const EnsPExon exon)1521 ajint ensExonGetPhaseEnd(const EnsPExon exon)
1522 {
1523     return (exon) ? exon->PhaseEnd : 0;
1524 }
1525 
1526 
1527 
1528 
1529 /* @func ensExonGetPhaseStart *************************************************
1530 **
1531 ** Get the phase at start member of an Ensembl Exon.
1532 **
1533 ** @cc Bio::EnsEMBL::Exon::phase
1534 ** @param [r] exon [const EnsPExon] Ensembl Exon
1535 **
1536 ** @return [ajint] Start phase or 0
1537 **
1538 ** @release 6.4.0
1539 ** @@
1540 **
1541 ** Get or set the phase of the Exon, which tells the translation machinery,
1542 ** which makes a peptide from the DNA, where to start.
1543 **
1544 ** The Ensembl phase convention can be thought of as "the number of bases of
1545 ** the first codon which are on the previous exon". It is therefore 0, 1 or 2
1546 ** or -1 if the exon is non-coding. In ASCII art, with alternate codons
1547 ** represented by '###' and '+++':
1548 **
1549 **       Previous Exon   Intron   This Exon
1550 **    ...-------------            -------------...
1551 **
1552 **    5'                    Phase                3'
1553 **    ...#+++###+++###          0 +++###+++###+...
1554 **    ...+++###+++###+          1 ++###+++###++...
1555 **    ...++###+++###++          2 +###+++###+++...
1556 **
1557 ** Here is another explanation from Ewan:
1558 **
1559 ** Phase means the place where the intron lands inside the codon - 0 between
1560 ** codons, 1 between the 1st and second base, 2 between the second and 3rd
1561 ** base. Exons therefore have a start phase and an end phase, but introns have
1562 ** just one phase.
1563 ******************************************************************************/
1564 
ensExonGetPhaseStart(const EnsPExon exon)1565 ajint ensExonGetPhaseStart(const EnsPExon exon)
1566 {
1567     return (exon) ? exon->PhaseStart : 0;
1568 }
1569 
1570 
1571 
1572 
1573 /* @func ensExonGetStableidentifier *******************************************
1574 **
1575 ** Get the stable identifier member of an Ensembl Exon.
1576 **
1577 ** @cc Bio::EnsEMBL::Exon::stable_id
1578 ** @param [r] exon [const EnsPExon] Ensembl Exon
1579 **
1580 ** @return [AjPStr] Stable identifier or NULL
1581 **
1582 ** @release 6.4.0
1583 ** @@
1584 ******************************************************************************/
1585 
ensExonGetStableidentifier(const EnsPExon exon)1586 AjPStr ensExonGetStableidentifier(const EnsPExon exon)
1587 {
1588     return (exon) ? exon->Stableidentifier : NULL;
1589 }
1590 
1591 
1592 
1593 
1594 /* @func ensExonGetVersion ****************************************************
1595 **
1596 ** Get the version member of an Ensembl Exon.
1597 **
1598 ** @cc Bio::EnsEMBL::Exon::version
1599 ** @param [r] exon [const EnsPExon] Ensembl Exon
1600 **
1601 ** @return [ajuint] Version or 0U
1602 **
1603 ** @release 6.2.0
1604 ** @@
1605 ******************************************************************************/
1606 
ensExonGetVersion(const EnsPExon exon)1607 ajuint ensExonGetVersion(const EnsPExon exon)
1608 {
1609     return (exon) ? exon->Version : 0U;
1610 }
1611 
1612 
1613 
1614 
1615 /* @section load on demand ****************************************************
1616 **
1617 ** Functions for returning members of an Ensembl Exon object,
1618 ** which may need loading from an Ensembl SQL database on demand.
1619 **
1620 ** @fdata [EnsPExon]
1621 **
1622 ** @nam3rule Load Return Ensembl Exon attribute(s) loaded on demand
1623 ** @nam4rule Supportingfeatures Return all supporting
1624 **                              Ensembl Base Align Feature objects
1625 **
1626 ** @argrule * exon [EnsPExon] Exon
1627 **
1628 ** @valrule Supportingfeatures [const AjPList] AJAX List of
1629 ** Ensembl Base Align Feature objects or NULL
1630 **
1631 ** @fcategory use
1632 ******************************************************************************/
1633 
1634 
1635 
1636 
1637 /* @func ensExonLoadSupportingfeatures ****************************************
1638 **
1639 ** Load all Ensembl Supporting Feature objects for this Ensembl Transcript.
1640 **
1641 ** This is not a simple accessor function, it will fetch
1642 ** Ensembl Base Align Feature objects of type 'dna' and 'protein' from the
1643 ** Ensembl Core database in case the AJAX List is not defined.
1644 **
1645 ** @cc Bio::EnsEMBL::Exon::get_all_supporting_features
1646 ** @param [u] exon [EnsPExon] Ensembl Exon
1647 **
1648 ** @return [const AjPList] AJAX List of Ensembl Base Align Feature objects
1649 ** or NULL
1650 **
1651 ** @release 6.4.0
1652 ** @@
1653 ******************************************************************************/
1654 
ensExonLoadSupportingfeatures(EnsPExon exon)1655 const AjPList ensExonLoadSupportingfeatures(EnsPExon exon)
1656 {
1657     EnsPDatabaseadaptor dba = NULL;
1658 
1659     EnsPSupportingfeatureadaptor sfa = NULL;
1660 
1661     if (!exon)
1662         return NULL;
1663 
1664     if (exon->Supportingfeatures)
1665         return exon->Supportingfeatures;
1666 
1667     if (!exon->Adaptor)
1668     {
1669         ajDebug("ensExonLoadSupportingfeatures cannot fetch "
1670                 "Ensembl Base Align Features object for an Ensembl Exon "
1671                 "without an Ensembl Exon Adaptor.\n");
1672 
1673         return NULL;
1674     }
1675 
1676     dba = ensExonadaptorGetDatabaseadaptor(exon->Adaptor);
1677 
1678     sfa = ensRegistryGetSupportingfeatureadaptor(dba);
1679 
1680     exon->Supportingfeatures = ajListNew();
1681 
1682     ensSupportingfeatureadaptorFetchAllbyExon(
1683         sfa,
1684         exon,
1685         exon->Supportingfeatures);
1686 
1687     return exon->Supportingfeatures;
1688 }
1689 
1690 
1691 
1692 
1693 /* @section member assignment *************************************************
1694 **
1695 ** Functions for assigning members of an Ensembl Exon object.
1696 **
1697 ** @fdata [EnsPExon]
1698 **
1699 ** @nam3rule Set Set one member of an Ensembl Exon
1700 ** @nam4rule Adaptor Set the Ensembl Exon Adaptor
1701 ** @nam4rule Constitutive Set the constitutive flag
1702 ** @nam4rule Current Set the current flag
1703 ** @nam4rule Date Set a date
1704 ** @nam5rule Creation Set the date of creation
1705 ** @nam5rule Modification Set the date of modification
1706 ** @nam4rule Feature Set the Ensembl Feature
1707 ** @nam4rule Identifier Set the SQL database-internal identifier
1708 ** @nam4rule Phase Set a phase
1709 ** @nam5rule PhaseEnd Set the phase at end
1710 ** @nam5rule PhaseStart Set the phase at start
1711 ** @nam4rule Stableidentifier Set the stable identifier
1712 ** @nam4rule Version Set the version
1713 **
1714 ** @argrule * exon [EnsPExon] Ensembl Exon object
1715 **
1716 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
1717 ** @argrule Adaptor ea [EnsPExonadaptor] Ensembl Exon Adaptor
1718 ** @argrule Constitutive constitutive [AjBool] Constitutive attribute
1719 ** @argrule Current current [AjBool] Current attribute
1720 ** @argrule DateCreation cdate [AjPStr] Creation date
1721 ** @argrule DateModification mdate [AjPStr] Modification date
1722 ** @argrule Feature feature [EnsPFeature] Ensembl Feature
1723 ** @argrule Identifier identifier [ajuint] SQL database-internal identifier
1724 ** @argrule PhaseEnd ephase [ajint] Phase at end
1725 ** @argrule PhaseStart sphase [ajint] Phase at start
1726 ** @argrule Stableidentifier stableid [AjPStr] Stable identifier
1727 ** @argrule Version version [ajuint] Version
1728 **
1729 ** @fcategory modify
1730 ******************************************************************************/
1731 
1732 
1733 
1734 
1735 /* @func ensExonSetAdaptor ****************************************************
1736 **
1737 ** Set the Ensembl Exon Adaptor member of an Ensembl Exon.
1738 **
1739 ** @cc Bio::EnsEMBL::Storable::adaptor
1740 ** @param [u] exon [EnsPExon] Ensembl Exon
1741 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
1742 **
1743 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1744 **
1745 ** @release 6.2.0
1746 ** @@
1747 ******************************************************************************/
1748 
ensExonSetAdaptor(EnsPExon exon,EnsPExonadaptor ea)1749 AjBool ensExonSetAdaptor(EnsPExon exon, EnsPExonadaptor ea)
1750 {
1751     if (!exon)
1752         return ajFalse;
1753 
1754     exon->Adaptor = ea;
1755 
1756     return ajTrue;
1757 }
1758 
1759 
1760 
1761 
1762 /* @func ensExonSetConstitutive ***********************************************
1763 **
1764 ** Set the constitutive member of an Ensembl Exon.
1765 **
1766 ** @cc Bio::EnsEMBL::Exon::is_constitutive
1767 ** @param [u] exon [EnsPExon] Ensembl Exon
1768 ** @param [r] constitutive [AjBool] Constitutive attribute
1769 **
1770 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1771 **
1772 ** @release 6.2.0
1773 ** @@
1774 ******************************************************************************/
1775 
ensExonSetConstitutive(EnsPExon exon,AjBool constitutive)1776 AjBool ensExonSetConstitutive(EnsPExon exon, AjBool constitutive)
1777 {
1778     if (!exon)
1779         return ajFalse;
1780 
1781     exon->Constitutive = constitutive;
1782 
1783     return ajTrue;
1784 }
1785 
1786 
1787 
1788 
1789 /* @func ensExonSetCurrent ****************************************************
1790 **
1791 ** Set the current member of an Ensembl Exon.
1792 **
1793 ** @cc Bio::EnsEMBL::Exon::is_current
1794 ** @param [u] exon [EnsPExon] Ensembl Exon
1795 ** @param [r] current [AjBool] Current attribute
1796 **
1797 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1798 **
1799 ** @release 6.2.0
1800 ** @@
1801 ******************************************************************************/
1802 
ensExonSetCurrent(EnsPExon exon,AjBool current)1803 AjBool ensExonSetCurrent(EnsPExon exon, AjBool current)
1804 {
1805     if (!exon)
1806         return ajFalse;
1807 
1808     exon->Current = current;
1809 
1810     return ajTrue;
1811 }
1812 
1813 
1814 
1815 
1816 /* @func ensExonSetDateCreation ***********************************************
1817 **
1818 ** Set the date of creation member of an Ensembl Exon.
1819 **
1820 ** @cc Bio::EnsEMBL::Exon::created_date
1821 ** @param [u] exon [EnsPExon] Ensembl Exon
1822 ** @param [u] cdate [AjPStr] Creation date
1823 **
1824 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1825 **
1826 ** @release 6.4.0
1827 ** @@
1828 ******************************************************************************/
1829 
ensExonSetDateCreation(EnsPExon exon,AjPStr cdate)1830 AjBool ensExonSetDateCreation(EnsPExon exon, AjPStr cdate)
1831 {
1832     if (!exon)
1833         return ajFalse;
1834 
1835     ajStrDel(&exon->DateCreation);
1836 
1837     exon->DateCreation = ajStrNewRef(cdate);
1838 
1839     return ajTrue;
1840 }
1841 
1842 
1843 
1844 
1845 /* @func ensExonSetDateModification *******************************************
1846 **
1847 ** Set the date of modification member of an Ensembl Exon.
1848 **
1849 ** @cc Bio::EnsEMBL::Exon::modified_date
1850 ** @param [u] exon [EnsPExon] Ensembl Exon
1851 ** @param [u] mdate [AjPStr] Modification date
1852 **
1853 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1854 **
1855 ** @release 6.4.0
1856 ** @@
1857 ******************************************************************************/
1858 
ensExonSetDateModification(EnsPExon exon,AjPStr mdate)1859 AjBool ensExonSetDateModification(EnsPExon exon, AjPStr mdate)
1860 {
1861     if (!exon)
1862         return ajFalse;
1863 
1864     ajStrDel(&exon->DateModification);
1865 
1866     exon->DateModification = ajStrNewRef(mdate);
1867 
1868     return ajTrue;
1869 }
1870 
1871 
1872 
1873 
1874 /* @func ensExonSetFeature ****************************************************
1875 **
1876 ** Set the Ensembl Feature member of an Ensembl Exon.
1877 **
1878 ** @cc Bio::EnsEMBL::Exon::slice
1879 ** @cc Bio::EnsEMBL::Exon::start
1880 ** @cc Bio::EnsEMBL::Exon::end
1881 ** @cc Bio::EnsEMBL::Exon::strand
1882 ** @cc Bio::EnsEMBL::Exon::move
1883 ** @param [u] exon [EnsPExon] Ensembl Exon
1884 ** @param [u] feature [EnsPFeature] Ensembl Feature
1885 **
1886 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1887 **
1888 ** @release 6.2.0
1889 ** @@
1890 ******************************************************************************/
1891 
ensExonSetFeature(EnsPExon exon,EnsPFeature feature)1892 AjBool ensExonSetFeature(EnsPExon exon, EnsPFeature feature)
1893 {
1894     AjIList iter = NULL;
1895 
1896     EnsPBasealignfeature baf  = NULL;
1897     EnsPBasealignfeature nbaf = NULL;
1898 
1899     EnsPSlice eslice = NULL;
1900 
1901     if (ajDebugTest("ensExonSetFeature"))
1902     {
1903         ajDebug("ensExonSetFeature\n"
1904                 "  exon %p\n"
1905                 "  feature %p\n",
1906                 exon,
1907                 feature);
1908 
1909         ensExonTrace(exon, 1);
1910 
1911         ensFeatureTrace(feature, 1);
1912     }
1913 
1914     if (!exon)
1915         return ajFalse;
1916 
1917     if (!feature)
1918         return ajFalse;
1919 
1920     /* Replace the current Feature. */
1921 
1922     ensFeatureDel(&exon->Feature);
1923 
1924     exon->Feature = ensFeatureNewRef(feature);
1925 
1926     /* Clear the sequence cache. */
1927 
1928     ajStrDel(&exon->SequenceCache);
1929 
1930     /*
1931     ** Transfer Ensembl Base Align Feature objects onto the new
1932     ** Feature Slice.
1933     */
1934 
1935     if (!exon->Supportingfeatures)
1936         return ajTrue;
1937 
1938     eslice = ensFeatureGetSlice(exon->Feature);
1939 
1940     iter = ajListIterNew(exon->Supportingfeatures);
1941 
1942     while (!ajListIterDone(iter))
1943     {
1944         baf = (EnsPBasealignfeature) ajListIterGet(iter);
1945 
1946         ajListIterRemove(iter);
1947 
1948         nbaf = ensBasealignfeatureTransfer(baf, eslice);
1949 
1950         if (!nbaf)
1951         {
1952             ajDebug("ensExonSetFeature could not transfer Base Align Feature "
1953                     "onto new Ensembl Feature Slice.");
1954 
1955             ensBasealignfeatureTrace(baf, 1);
1956         }
1957 
1958         ajListIterInsert(iter, (void *) nbaf);
1959 
1960         /* Advance the AJAX List Iterator after the insert. */
1961 
1962         (void) ajListIterGet(iter);
1963 
1964         ensBasealignfeatureDel(&baf);
1965     }
1966 
1967     ajListIterDel(&iter);
1968 
1969     return ajTrue;
1970 }
1971 
1972 
1973 
1974 
1975 /* @func ensExonSetIdentifier *************************************************
1976 **
1977 ** Set the SQL database-internal identifier member of an Ensembl Exon.
1978 **
1979 ** @cc Bio::EnsEMBL::Storable::dbID
1980 ** @param [u] exon [EnsPExon] Ensembl Exon
1981 ** @param [r] identifier [ajuint] SQL database-internal identifier
1982 **
1983 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
1984 **
1985 ** @release 6.2.0
1986 ** @@
1987 ******************************************************************************/
1988 
ensExonSetIdentifier(EnsPExon exon,ajuint identifier)1989 AjBool ensExonSetIdentifier(EnsPExon exon, ajuint identifier)
1990 {
1991     if (!exon)
1992         return ajFalse;
1993 
1994     exon->Identifier = identifier;
1995 
1996     return ajTrue;
1997 }
1998 
1999 
2000 
2001 
2002 /* @func ensExonSetPhaseEnd ***************************************************
2003 **
2004 ** Set the phase at end member of an Ensembl Exon.
2005 **
2006 ** @cc Bio::EnsEMBL::Exon::end_phase
2007 ** @param [u] exon [EnsPExon] Ensembl Exon
2008 ** @param [r] ephase [ajint] End phase
2009 **
2010 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2011 **
2012 ** @release 6.4.0
2013 ** @@
2014 ******************************************************************************/
2015 
ensExonSetPhaseEnd(EnsPExon exon,ajint ephase)2016 AjBool ensExonSetPhaseEnd(EnsPExon exon, ajint ephase)
2017 {
2018     if (!exon)
2019         return ajFalse;
2020 
2021     exon->PhaseEnd = ephase;
2022 
2023     return ajTrue;
2024 }
2025 
2026 
2027 
2028 
2029 /* @func ensExonSetPhaseStart *************************************************
2030 **
2031 ** Set the phase at start member of an Ensembl Exon.
2032 **
2033 ** @cc Bio::EnsEMBL::Exon::phase
2034 ** @param [u] exon [EnsPExon] Ensembl Exon
2035 ** @param [r] sphase [ajint] Start phase
2036 **
2037 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2038 **
2039 ** @release 6.4.0
2040 ** @@
2041 ******************************************************************************/
2042 
ensExonSetPhaseStart(EnsPExon exon,ajint sphase)2043 AjBool ensExonSetPhaseStart(EnsPExon exon, ajint sphase)
2044 {
2045     if (!exon)
2046         return ajFalse;
2047 
2048     exon->PhaseStart = sphase;
2049 
2050     return ajTrue;
2051 }
2052 
2053 
2054 
2055 
2056 /* @func ensExonSetStableidentifier *******************************************
2057 **
2058 ** Set the stable identifier member of an Ensembl Exon.
2059 **
2060 ** @cc Bio::EnsEMBL::Exon::stable_id
2061 ** @param [u] exon [EnsPExon] Ensembl Exon
2062 ** @param [u] stableid [AjPStr] Stable identifier
2063 **
2064 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2065 **
2066 ** @release 6.4.0
2067 ** @@
2068 ******************************************************************************/
2069 
ensExonSetStableidentifier(EnsPExon exon,AjPStr stableid)2070 AjBool ensExonSetStableidentifier(EnsPExon exon, AjPStr stableid)
2071 {
2072     if (!exon)
2073         return ajFalse;
2074 
2075     ajStrDel(&exon->Stableidentifier);
2076 
2077     exon->Stableidentifier = ajStrNewRef(stableid);
2078 
2079     return ajTrue;
2080 }
2081 
2082 
2083 
2084 
2085 /* @func ensExonSetVersion ****************************************************
2086 **
2087 ** Set the version member of an Ensembl Exon.
2088 **
2089 ** @cc Bio::EnsEMBL::Exon::version
2090 ** @param [u] exon [EnsPExon] Ensembl Exon
2091 ** @param [r] version [ajuint] Version
2092 **
2093 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2094 **
2095 ** @release 6.2.0
2096 ** @@
2097 ******************************************************************************/
2098 
ensExonSetVersion(EnsPExon exon,ajuint version)2099 AjBool ensExonSetVersion(EnsPExon exon, ajuint version)
2100 {
2101     if (!exon)
2102         return ajFalse;
2103 
2104     exon->Version = version;
2105 
2106     return ajTrue;
2107 }
2108 
2109 
2110 
2111 
2112 /* @section debugging *********************************************************
2113 **
2114 ** Functions for reporting of an Ensembl Exon object.
2115 **
2116 ** @fdata [EnsPExon]
2117 **
2118 ** @nam3rule Trace Report Ensembl Exon members to debug file
2119 **
2120 ** @argrule Trace exon [const EnsPExon] Ensembl Exon
2121 ** @argrule Trace level [ajuint] Indentation level
2122 **
2123 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
2124 **
2125 ** @fcategory misc
2126 ******************************************************************************/
2127 
2128 
2129 
2130 
2131 /* @func ensExonTrace *********************************************************
2132 **
2133 ** Trace an Ensembl Exon.
2134 **
2135 ** @param [r] exon [const EnsPExon] Ensembl Exon
2136 ** @param [r] level [ajuint] Indentation level
2137 **
2138 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2139 **
2140 ** @release 6.2.0
2141 ** @@
2142 ******************************************************************************/
2143 
ensExonTrace(const EnsPExon exon,ajuint level)2144 AjBool ensExonTrace(const EnsPExon exon, ajuint level)
2145 {
2146     AjIList iter = NULL;
2147 
2148     AjPStr indent = NULL;
2149     AjPStr tmpstr = NULL;
2150 
2151     EnsPBasealignfeature baf = NULL;
2152 
2153     if (!exon)
2154         return ajFalse;
2155 
2156     indent = ajStrNew();
2157 
2158     ajStrAppendCountK(&indent, ' ', level * 2);
2159 
2160     ajDebug("%SensExonTrace %p\n"
2161             "%S  Use %u\n"
2162             "%S  Identifier %u\n"
2163             "%S  Adaptor %p\n"
2164             "%S  Feature %p\n"
2165             "%S  PhaseStart %d\n"
2166             "%S  PhaseEnd %d\n"
2167             "%S  Current '%B'\n"
2168             "%S  Constitutive '%B'\n"
2169             "%S  Stableidentifier '%S'\n"
2170             "%S  Version %u\n"
2171             "%S  DateCreation '%S'\n"
2172             "%S  DateModification '%S'\n"
2173             "%S  SequenceCache %p\n"
2174             "%S  Supportingfeatures %p\n",
2175             indent, exon,
2176             indent, exon->Use,
2177             indent, exon->Identifier,
2178             indent, exon->Adaptor,
2179             indent, exon->Feature,
2180             indent, exon->PhaseStart,
2181             indent, exon->PhaseEnd,
2182             indent, exon->Current,
2183             indent, exon->Constitutive,
2184             indent, exon->Stableidentifier,
2185             indent, exon->Version,
2186             indent, exon->DateCreation,
2187             indent, exon->DateModification,
2188             indent, exon->SequenceCache,
2189             indent, exon->Supportingfeatures);
2190 
2191     ensFeatureTrace(exon->Feature, level + 1);
2192 
2193     if (exon->SequenceCache)
2194     {
2195         /*
2196         ** For sequences longer than 40 characters use a
2197         ** '20 ... 20' notation.
2198         */
2199 
2200         if (ajStrGetLen(exon->SequenceCache) > 40)
2201         {
2202             tmpstr = ajStrNew();
2203 
2204             ajStrAssignSubS(&tmpstr, exon->SequenceCache, 0, 19);
2205 
2206             ajStrAppendC(&tmpstr, " ... ");
2207 
2208             ajStrAppendSubS(&tmpstr, exon->SequenceCache, -20, -1);
2209 
2210             ajDebug("%S  Sequence cache: '%S'\n", indent, tmpstr);
2211 
2212             ajStrDel(&tmpstr);
2213         }
2214         else
2215             ajDebug("%S  Sequence cache: '%S'\n", indent, exon->SequenceCache);
2216     }
2217 
2218     /* Trace the AJAX List of supporting Ensembl Base Align Feature objects. */
2219 
2220     if (exon->Supportingfeatures)
2221     {
2222         ajDebug("%S    AJAX List %p of Ensembl Base Align Feature objects:\n",
2223                 indent, exon->Supportingfeatures);
2224 
2225         iter = ajListIterNewread(exon->Supportingfeatures);
2226 
2227         while (!ajListIterDone(iter))
2228         {
2229             baf = (EnsPBasealignfeature) ajListIterGet(iter);
2230 
2231             ensBasealignfeatureTrace(baf, level + 2);
2232         }
2233 
2234         ajListIterDel(&iter);
2235     }
2236 
2237     ajStrDel(&indent);
2238 
2239     return ajTrue;
2240 }
2241 
2242 
2243 
2244 
2245 /* @section calculate *********************************************************
2246 **
2247 ** Functions for calculating information from an Ensembl Exon object.
2248 **
2249 ** @fdata [EnsPExon]
2250 **
2251 ** @nam3rule Calculate Calculate Ensembl Exon information
2252 ** @nam4rule Frame Calculate the coding frame
2253 ** @nam4rule Memsize Calculate the memory size in bytes
2254 ** @nam4rule Slice      Calculate Ensembl Exon coordinates relative to an
2255 **                      Ensembl Slice
2256 ** @nam5rule Coding Calculate Ensembl Exon coding coordinates
2257 ** @nam6rule End    Calculate the Ensembl Exon coding start coordinate
2258 ** @nam6rule Start  Calculate the Ensembl Exon coding end coordinate
2259 ** @nam4rule Transcript Calculate Ensembl Exon coordinates relative to an
2260 **                      Ensembl Transcript
2261 ** @nam5rule Coding Calculate Ensembl Exon coding coordinates
2262 ** @nam6rule End    Calculate the Ensembl Exon coding start coordinate
2263 ** @nam6rule Start  Calculate the Ensembl Exon coding end coordinate
2264 ** @nam5rule End    Calculate the Ensembl Exon end coordinate
2265 ** @nam5rule Start  Calculate the Ensembl Exon start coordinate
2266 **
2267 ** @argrule Frame exon [const EnsPExon] Ensembl Exon
2268 ** @argrule Memsize exon [const EnsPExon] Ensembl Exon
2269 ** @argrule SliceCoding exon [EnsPExon] Ensembl Exon
2270 ** @argrule SliceCoding transcript [EnsPTranscript] Ensembl Transcript
2271 ** @argrule SliceCoding translation [EnsPTranslation] Ensembl Translation
2272 ** @argrule TranscriptCoding exon [EnsPExon] Ensembl Exon
2273 ** @argrule TranscriptCoding transcript [EnsPTranscript] Ensembl Transcript
2274 ** @argrule TranscriptCoding translation [EnsPTranslation] Ensembl Translation
2275 ** @argrule TranscriptEnd exon [EnsPExon] Ensembl Exon
2276 ** @argrule TranscriptEnd transcript [EnsPTranscript] Ensembl Transcript
2277 ** @argrule TranscriptStart exon [EnsPExon] Ensembl Exon
2278 ** @argrule TranscriptStart transcript [EnsPTranscript] Ensembl Transcript
2279 **
2280 ** @valrule Frame [ajint] Coding frame or 0
2281 ** @valrule Memsize [size_t] Memory size in bytes or 0
2282 ** @valrule SliceCodingEnd [ajint] End coordinate or 0
2283 ** @valrule SliceCodingStart [ajint] Start coordinate or 0
2284 ** @valrule TranscriptCodingEnd [ajuint] End coordinate or 0U
2285 ** @valrule TranscriptCodingStart [ajuint] Start coordinate or 0U
2286 ** @valrule TranscriptEnd [ajuint] End coordinate or 0U
2287 ** @valrule TranscriptStart [ajuint] Start coordinate or 0U
2288 **
2289 ** @fcategory misc
2290 ******************************************************************************/
2291 
2292 
2293 
2294 
2295 /* @func ensExonCalculateFrame ************************************************
2296 **
2297 ** Calculate the coding frame of an Ensembl Exon on an Ensembl Slice.
2298 ** The coding frame can be 0, 1, 2 or -1 for Exon objects that are not coding.
2299 **
2300 ** @cc Bio::EnsEMBL::Exon:frame
2301 ** @param [r] exon [const EnsPExon] Ensembl Exon
2302 **
2303 ** @return [ajint] Coding frame or 0
2304 **
2305 ** @release 6.4.0
2306 ** @@
2307 ******************************************************************************/
2308 
ensExonCalculateFrame(const EnsPExon exon)2309 ajint ensExonCalculateFrame(const EnsPExon exon)
2310 {
2311     if (!exon)
2312         return 0;
2313 
2314     if (exon->PhaseStart == -1)
2315         return -1;
2316 
2317     return (ensFeatureGetStart(exon->Feature) + 3 - exon->PhaseStart) % 3;
2318 
2319 #if AJFALSE
2320     if (exon->PhaseStart == 0)
2321         return (ensFeatureGetStart(exon->Feature) + 3) % 3;
2322 
2323     if (exon->PhaseStart == 1)
2324         return (ensFeatureGetStart(exon->Feature) + 2) % 3;
2325 
2326     if (exon->PhaseStart == 2)
2327         return (ensFeatureGetStart(exon->Feature) + 1) % 3;
2328 
2329     ajDebug("ensExonCalculateFrame invalid start phase %d in exon %u.\n",
2330             exon->PhaseStart, exon->Identifier);
2331 
2332     return 0;
2333 #endif
2334 }
2335 
2336 
2337 
2338 
2339 /* @func ensExonCalculateMemsize **********************************************
2340 **
2341 ** Calculate the memory size in bytes of an Ensembl Exon.
2342 **
2343 ** @param [r] exon [const EnsPExon] Ensembl Exon
2344 **
2345 ** @return [size_t] Memory size in bytes or 0
2346 **
2347 ** @release 6.4.0
2348 ** @@
2349 ******************************************************************************/
2350 
ensExonCalculateMemsize(const EnsPExon exon)2351 size_t ensExonCalculateMemsize(const EnsPExon exon)
2352 {
2353     size_t size = 0;
2354 
2355     AjIList iter = NULL;
2356 
2357     EnsPBasealignfeature baf = NULL;
2358 
2359     if (!exon)
2360         return 0;
2361 
2362     size += sizeof (EnsOExon);
2363 
2364     size += ensFeatureCalculateMemsize(exon->Feature);
2365 
2366     if (exon->Stableidentifier)
2367     {
2368         size += sizeof (AjOStr);
2369 
2370         size += ajStrGetRes(exon->Stableidentifier);
2371     }
2372 
2373     if (exon->DateCreation)
2374     {
2375         size += sizeof (AjOStr);
2376 
2377         size += ajStrGetRes(exon->DateCreation);
2378     }
2379 
2380     if (exon->DateModification)
2381     {
2382         size += sizeof (AjOStr);
2383 
2384         size += ajStrGetRes(exon->DateModification);
2385     }
2386 
2387     if (exon->SequenceCache)
2388     {
2389         size += sizeof (AjOStr);
2390 
2391         size += ajStrGetRes(exon->SequenceCache);
2392     }
2393 
2394     /*
2395     ** Summarise the AJAX List of supporting
2396     ** Ensembl Base Align Feature objects.
2397     */
2398 
2399     if (exon->Supportingfeatures)
2400     {
2401         size += sizeof (AjOList);
2402 
2403         iter = ajListIterNewread(exon->Supportingfeatures);
2404 
2405         while (!ajListIterDone(iter))
2406         {
2407             baf = (EnsPBasealignfeature) ajListIterGet(iter);
2408 
2409             size += ensBasealignfeatureCalculateMemsize(baf);
2410         }
2411 
2412         ajListIterDel(&iter);
2413     }
2414 
2415     return size;
2416 }
2417 
2418 
2419 
2420 
2421 /* @func ensExonCalculateSliceCodingEnd ***************************************
2422 **
2423 ** Calculate the end coordinate of the coding region of an Ensembl Exon
2424 ** relaive to an Ensembl Slice.
2425 **
2426 ** @cc Bio::EnsEMBL::Exon::coding_region_end
2427 ** @param [u] exon [EnsPExon] Ensembl Exon
2428 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2429 ** @param [u] translation [EnsPTranslation] Ensembl Translation
2430 **
2431 ** @return [ajint] Coding end coordinate or 0
2432 **
2433 ** @release 6.4.0
2434 ** @@
2435 ******************************************************************************/
2436 
ensExonCalculateSliceCodingEnd(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation)2437 ajint ensExonCalculateSliceCodingEnd(EnsPExon exon,
2438                                      EnsPTranscript transcript,
2439                                      EnsPTranslation translation)
2440 {
2441     ajint scend = 0;
2442 
2443     EnsPExoncoordinates ec = NULL;
2444 
2445     if (!exon)
2446         return 0;
2447 
2448     if (!transcript)
2449         return 0;
2450 
2451     ec = ensExoncoordinatesNewIni(exon, transcript, translation);
2452 
2453     if (ec)
2454         scend = ec->SliceCodingEnd;
2455 
2456     ensExoncoordinatesDel(&ec);
2457 
2458     return scend;
2459 }
2460 
2461 
2462 
2463 
2464 /* @func ensExonCalculateSliceCodingStart *************************************
2465 **
2466 ** Calculate the start coordinate of the coding region of an Ensembl Exon
2467 ** relaive to an Ensembl Slice.
2468 **
2469 ** @cc Bio::EnsEMBL::Exon::coding_region_start
2470 ** @param [u] exon [EnsPExon] Ensembl Exon
2471 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2472 ** @param [u] translation [EnsPTranslation] Ensembl Translation
2473 **
2474 ** @return [ajint] Coding start coordinate or 0
2475 **
2476 ** @release 6.4.0
2477 ** @@
2478 ******************************************************************************/
2479 
ensExonCalculateSliceCodingStart(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation)2480 ajint ensExonCalculateSliceCodingStart(EnsPExon exon,
2481                                        EnsPTranscript transcript,
2482                                        EnsPTranslation translation)
2483 {
2484     ajint scstart = 0;
2485 
2486     EnsPExoncoordinates ec = NULL;
2487 
2488     if (!exon)
2489         return 0;
2490 
2491     if (!transcript)
2492         return 0;
2493 
2494     ec = ensExoncoordinatesNewIni(exon, transcript, translation);
2495 
2496     if (ec)
2497         scstart = ec->SliceCodingStart;
2498 
2499     ensExoncoordinatesDel(&ec);
2500 
2501     return scstart;
2502 }
2503 
2504 
2505 
2506 
2507 /* @func ensExonCalculateTranscriptCodingEnd **********************************
2508 **
2509 ** Calculate the end coordinate of the coding region of an Ensembl Exon
2510 ** relative to an Ensembl Transcript.
2511 **
2512 ** @cc Bio::EnsEMBL::Exon::cdna_coding_end
2513 ** @param [u] exon [EnsPExon] Ensembl Exon
2514 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2515 ** @param [u] translation [EnsPTranslation] Ensembl Translation
2516 **
2517 ** @return [ajuint] Coding end coordinate or 0U
2518 **
2519 ** @release 6.4.0
2520 ** @@
2521 ******************************************************************************/
2522 
ensExonCalculateTranscriptCodingEnd(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation)2523 ajuint ensExonCalculateTranscriptCodingEnd(EnsPExon exon,
2524                                            EnsPTranscript transcript,
2525                                            EnsPTranslation translation)
2526 {
2527     ajuint tcend = 0U;
2528 
2529     EnsPExoncoordinates ec = NULL;
2530 
2531     if (!exon)
2532         return 0U;
2533 
2534     if (!transcript)
2535         return 0U;
2536 
2537     ec = ensExoncoordinatesNewIni(exon, transcript, translation);
2538 
2539     if (ec)
2540         tcend = ec->TranscriptCodingEnd;
2541 
2542     ensExoncoordinatesDel(&ec);
2543 
2544     return tcend;
2545 }
2546 
2547 
2548 
2549 
2550 /* @func ensExonCalculateTranscriptCodingStart ********************************
2551 **
2552 ** Calculate the start coordinate of the coding region of an Ensembl Exon
2553 ** relative to an Ensembl Transcript.
2554 **
2555 ** @cc Bio::EnsEMBL::Exon::cdna_coding_start
2556 ** @param [u] exon [EnsPExon] Ensembl Exon
2557 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2558 ** @param [u] translation [EnsPTranslation] Ensembl Translation
2559 **
2560 ** @return [ajuint] Coding start coordinate or 0U
2561 **
2562 ** @release 6.4.0
2563 ** @@
2564 ******************************************************************************/
2565 
ensExonCalculateTranscriptCodingStart(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation)2566 ajuint ensExonCalculateTranscriptCodingStart(EnsPExon exon,
2567                                              EnsPTranscript transcript,
2568                                              EnsPTranslation translation)
2569 {
2570     ajuint tcstart = 0U;
2571 
2572     EnsPExoncoordinates ec = NULL;
2573 
2574     if (!exon)
2575         return 0U;
2576 
2577     if (!transcript)
2578         return 0U;
2579 
2580     ec = ensExoncoordinatesNewIni(exon, transcript, translation);
2581 
2582     if (ec)
2583         tcstart = ec->TranscriptCodingStart;
2584 
2585     ensExoncoordinatesDel(&ec);
2586 
2587     return tcstart;
2588 }
2589 
2590 
2591 
2592 
2593 /* @func ensExonCalculateTranscriptEnd ****************************************
2594 **
2595 ** Calculate the end coordinate of an Ensembl Exon relative to an
2596 ** Ensembl Transcript.
2597 **
2598 ** @cc Bio::EnsEMBL::Exon::cdna_end
2599 ** @param [u] exon [EnsPExon] Ensembl Exon
2600 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2601 **
2602 ** @return [ajuint] End coordinate or 0U
2603 **
2604 ** @release 6.4.0
2605 ** @@
2606 ******************************************************************************/
2607 
ensExonCalculateTranscriptEnd(EnsPExon exon,EnsPTranscript transcript)2608 ajuint ensExonCalculateTranscriptEnd(EnsPExon exon, EnsPTranscript transcript)
2609 {
2610     ajuint tend = 0U;
2611 
2612     EnsPExoncoordinates ec = NULL;
2613 
2614     if (!exon)
2615         return 0U;
2616 
2617     if (!transcript)
2618         return 0U;
2619 
2620     ec = ensExoncoordinatesNewIni(exon, transcript, (EnsPTranslation) NULL);
2621 
2622     if (ec)
2623         tend = ec->TranscriptEnd;
2624 
2625     ensExoncoordinatesDel(&ec);
2626 
2627     return tend;
2628 }
2629 
2630 
2631 
2632 
2633 /* @func ensExonCalculateTranscriptStart **************************************
2634 **
2635 ** Calculate the start coordinate of an Ensembl Exon relative to an
2636 ** Ensembl Transcript.
2637 **
2638 ** @cc Bio::EnsEMBL::Exon::cdna_start
2639 ** @param [u] exon [EnsPExon] Ensembl Exon
2640 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
2641 **
2642 ** @return [ajuint] Start coordinate or 0U
2643 **
2644 ** @release 6.4.0
2645 ** @@
2646 ******************************************************************************/
2647 
ensExonCalculateTranscriptStart(EnsPExon exon,EnsPTranscript transcript)2648 ajuint ensExonCalculateTranscriptStart(EnsPExon exon,
2649                                        EnsPTranscript transcript)
2650 {
2651     ajuint tstart = 0U;
2652 
2653     EnsPExoncoordinates ec = NULL;
2654 
2655     if (!exon)
2656         return 0U;
2657 
2658     if (!transcript)
2659         return 0U;
2660 
2661     ec = ensExoncoordinatesNewIni(exon, transcript, (EnsPTranslation) NULL);
2662 
2663     if (ec)
2664         tstart = ec->TranscriptStart;
2665 
2666     ensExoncoordinatesDel(&ec);
2667 
2668     return tstart;
2669 }
2670 
2671 
2672 
2673 
2674 /* @section map ***************************************************************
2675 **
2676 ** Functions for mapping Ensembl Exon objects between
2677 ** Ensembl Coordinate System objects.
2678 **
2679 ** @fdata [EnsPExon]
2680 **
2681 ** @nam3rule Transfer Transfer an Ensembl Exon
2682 ** @nam3rule Transform Transform an Ensembl Exon
2683 **
2684 ** @argrule * exon [EnsPExon] Ensembl Exon
2685 ** @argrule Transfer slice [EnsPSlice] Ensembl Slice
2686 ** @argrule Transform csname [const AjPStr]
2687 ** Ensembl Coordinate System name
2688 ** @argrule Transform csversion [const AjPStr]
2689 ** Ensembl Coordinate System version
2690 **
2691 ** @valrule * [EnsPExon] Ensembl Exon or NULL
2692 **
2693 ** @fcategory misc
2694 ******************************************************************************/
2695 
2696 
2697 
2698 
2699 /* @func ensExonTransfer ******************************************************
2700 **
2701 ** Transfer an Ensembl Exon onto another Ensembl Slice.
2702 **
2703 ** @cc Bio::EnsEMBL::Feature::transfer
2704 ** @param [u] exon [EnsPExon] Ensembl Exon
2705 ** @param [u] slice [EnsPSlice] Ensembl Slice
2706 ** @see ensFeatureTransfer
2707 **
2708 ** @return [EnsPExon] Ensembl Exon or NULL
2709 **
2710 ** @release 6.2.0
2711 ** @@
2712 ******************************************************************************/
2713 
ensExonTransfer(EnsPExon exon,EnsPSlice slice)2714 EnsPExon ensExonTransfer(EnsPExon exon, EnsPSlice slice)
2715 {
2716     EnsPExon newexon = NULL;
2717     EnsPFeature newfeature = NULL;
2718 
2719     if (!exon)
2720         return NULL;
2721 
2722     if (!slice)
2723         return NULL;
2724 
2725     newfeature = ensFeatureTransfer(exon->Feature, slice);
2726 
2727     if (!newfeature)
2728         return NULL;
2729 
2730     newexon = ensExonNewCpy(exon);
2731 
2732     ensExonSetFeature(newexon, newfeature);
2733 
2734     /*
2735     ** NOTE: The Exon-internal supporting features have already been
2736     ** transfered to the new Slice and the sequence cache has already been
2737     ** cleared by the ensExonSetFeature function.
2738     */
2739 
2740     ensFeatureDel(&newfeature);
2741 
2742     return newexon;
2743 }
2744 
2745 
2746 
2747 
2748 /* @func ensExonTransform *****************************************************
2749 **
2750 ** Transform an Ensembl Exon into another Ensembl Coordinate System.
2751 **
2752 ** @cc Bio::EnsEMBL::Feature::transform
2753 ** @param [u] exon [EnsPExon] Ensembl Exon
2754 ** @param [r] csname [const AjPStr] Ensembl Coordinate System name
2755 ** @param [r] csversion [const AjPStr] Ensembl Coordinate System version
2756 ** @see ensFeatureTransform
2757 **
2758 ** @return [EnsPExon] Ensembl Exon or NULL
2759 **
2760 ** @release 6.2.0
2761 ** @@
2762 ******************************************************************************/
2763 
ensExonTransform(EnsPExon exon,const AjPStr csname,const AjPStr csversion)2764 EnsPExon ensExonTransform(EnsPExon exon,
2765                           const AjPStr csname,
2766                           const AjPStr csversion)
2767 {
2768     EnsPExon nexon       = NULL;
2769     EnsPFeature nfeature = NULL;
2770 
2771     if (!exon)
2772         return NULL;
2773 
2774     if (!csname)
2775         return NULL;
2776 
2777     if (!csversion)
2778         return NULL;
2779 
2780     nfeature = ensFeatureTransform(exon->Feature,
2781                                    csname,
2782                                    csversion,
2783                                    (EnsPSlice) NULL);
2784 
2785     if (!nfeature)
2786         return NULL;
2787 
2788     nexon = ensExonNewCpy(exon);
2789 
2790     ensExonSetFeature(nexon, nfeature);
2791 
2792     /*
2793     ** NOTE: The Exon-internal supporting features have already been
2794     ** transfered to the new Slice and the sequence cache has already been
2795     ** cleared by the ensExonSetFeature function.
2796     */
2797 
2798     return nexon;
2799 }
2800 
2801 
2802 
2803 
2804 /* @section fetch *************************************************************
2805 **
2806 ** Functions for fetching information from an Ensembl Exon object.
2807 **
2808 ** @fdata [EnsPExon]
2809 **
2810 ** @nam3rule Fetch Fetch Ensembl Exon information
2811 ** @nam4rule Displayidentifier Fetch the display identifier
2812 ** @nam4rule Sequence Fetch the sequence
2813 ** @nam5rule Slice Fetch the sequence of the Ensembl Slice
2814 ** covered by an Ensembl Exon
2815 ** @nam5rule Translation Fetch the sequence of the Ensembl Translation
2816 ** covered by an Ensembl Exon
2817 ** @nam6rule Seq Fetch the sequence as AJAX Sequence object
2818 ** @nam6rule Str Fetch the sequence as AJAX String object
2819 **
2820 ** @argrule Displayidentifier exon [const EnsPExon] Ensembl Exon
2821 ** @argrule Displayidentifier Pidentifier [AjPStr*] Display identifier address
2822 ** @argrule Sequence exon [EnsPExon] Ensembl Exon
2823 ** @argrule Translation transcript [EnsPTranscript] Ensembl Transcript
2824 ** @argrule Translation translation [EnsPTranslation] Ensembl Translation
2825 ** @argrule Seq Psequence [AjPSeq*] AJAX Sequence object address
2826 ** @argrule Str Psequence [AjPStr*] AJAX String object address
2827 **
2828 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
2829 **
2830 ** @fcategory misc
2831 ******************************************************************************/
2832 
2833 
2834 
2835 
2836 /* @func ensExonFetchDisplayidentifier ****************************************
2837 **
2838 ** Fetch the display identifier of an Ensembl Exon.
2839 ** This will return the stable identifier, the SQL database-internal identifier
2840 ** or the Exon memory address in this order.
2841 ** The caller is responsible for deleting the AJAX String.
2842 **
2843 ** @cc Bio::EnsEMBL::Exon:display_id
2844 ** @param [r] exon [const EnsPExon] Ensembl Exon
2845 ** @param [wP] Pidentifier [AjPStr*] Display identifier address
2846 **
2847 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2848 **
2849 ** @release 6.4.0
2850 ** @@
2851 ******************************************************************************/
2852 
ensExonFetchDisplayidentifier(const EnsPExon exon,AjPStr * Pidentifier)2853 AjBool ensExonFetchDisplayidentifier(const EnsPExon exon, AjPStr *Pidentifier)
2854 {
2855     if (!exon)
2856         return ajFalse;
2857 
2858     if (!Pidentifier)
2859         return ajFalse;
2860 
2861     if (exon->Stableidentifier && ajStrGetLen(exon->Stableidentifier))
2862     {
2863         if (*Pidentifier)
2864             ajStrAssignS(Pidentifier, exon->Stableidentifier);
2865         else
2866             *Pidentifier = ajStrNewS(exon->Stableidentifier);
2867     }
2868     else if (exon->Identifier)
2869     {
2870         if (*Pidentifier)
2871             *Pidentifier = ajFmtPrintS(Pidentifier, "%u", exon->Identifier);
2872         else
2873             *Pidentifier = ajFmtStr("%u", exon->Identifier);
2874     }
2875     else
2876     {
2877         if (*Pidentifier)
2878             *Pidentifier = ajFmtPrintS(Pidentifier, "%p", exon);
2879         else
2880             *Pidentifier = ajFmtStr("%p", exon);
2881     }
2882 
2883     return ajTrue;
2884 }
2885 
2886 
2887 
2888 
2889 /* @func ensExonFetchSequenceSliceSeq *****************************************
2890 **
2891 ** Fetch the sequence of an Ensembl Slice covered by an Ensembl Exon as
2892 ** AJAX Sequence.
2893 **
2894 ** The caller is responsible for deleting the AJAX Sequence.
2895 **
2896 ** @cc Bio::EnsEMBL::Exon:seq
2897 ** @param [u] exon [EnsPExon] Ensembl Exon
2898 ** @param [wP] Psequence [AjPSeq*] AJAX Sequence object address
2899 **
2900 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2901 **
2902 ** @release 6.4.0
2903 ** @@
2904 ******************************************************************************/
2905 
ensExonFetchSequenceSliceSeq(EnsPExon exon,AjPSeq * Psequence)2906 AjBool ensExonFetchSequenceSliceSeq(EnsPExon exon, AjPSeq *Psequence)
2907 {
2908     AjPStr name     = NULL;
2909     AjPStr sequence = NULL;
2910 
2911     if (!exon)
2912         return ajFalse;
2913 
2914     if (!Psequence)
2915         return ajFalse;
2916 
2917     /*
2918     ** It is sligtly more efficient, if undefined AJAX String objects are
2919     ** directly allocated by the following functions to their final size.
2920     */
2921 
2922     ensExonFetchDisplayidentifier(exon, &name);
2923     ensExonFetchSequenceSliceStr(exon, &sequence);
2924 
2925     if (*Psequence)
2926     {
2927         ajSeqClear(*Psequence);
2928 
2929         ajSeqAssignNameS(*Psequence, name);
2930         ajSeqAssignSeqS(*Psequence, sequence);
2931     }
2932     else
2933         *Psequence = ajSeqNewNameS(sequence, name);
2934 
2935     ajSeqSetNuc(*Psequence);
2936 
2937     ajStrDel(&name);
2938     ajStrDel(&sequence);
2939 
2940     return ajTrue;
2941 }
2942 
2943 
2944 
2945 
2946 /* @func ensExonFetchSequenceSliceStr *****************************************
2947 **
2948 ** Fetch the sequence of an Ensembl Slice covered by an Ensembl Exon as
2949 ** AJAX String.
2950 **
2951 ** The caller is responsible for deleting the AJAX String.
2952 **
2953 ** @param [u] exon [EnsPExon] Ensembl Exon
2954 ** @param [wP] Psequence [AjPStr*] AJAX String object address
2955 **
2956 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
2957 **
2958 ** @release 6.4.0
2959 ** @@
2960 ******************************************************************************/
2961 
ensExonFetchSequenceSliceStr(EnsPExon exon,AjPStr * Psequence)2962 AjBool ensExonFetchSequenceSliceStr(EnsPExon exon, AjPStr *Psequence)
2963 {
2964     ajint mpoint = 0;
2965 
2966     AjBool circular = AJFALSE;
2967 
2968     AjPStr sequence1 = NULL;
2969     AjPStr sequence2 = NULL;
2970 
2971     EnsPFeature feature = NULL;
2972 
2973     EnsPSlice slice = NULL;
2974 
2975     if (!exon)
2976         return ajFalse;
2977 
2978     if (!Psequence)
2979         return ajFalse;
2980 
2981     if (*Psequence)
2982         ajStrAssignClear(Psequence);
2983 
2984     feature = exon->Feature;
2985 
2986     if (!feature)
2987     {
2988         ajWarn("ensExonFetchSequenceSliceStr cannot get sequence without an "
2989                "Ensembl Feature attached to the Ensembl Exon '%u:%S'.\n",
2990                exon->Identifier, exon->Stableidentifier);
2991 
2992         return ajFalse;
2993     }
2994 
2995     slice = ensFeatureGetSlice(feature);
2996 
2997     if (!slice)
2998     {
2999         ajWarn("ensExonFetchSequenceSliceStr cannot get sequence without an "
3000                "Ensembl Slice attached to the Ensembl Feature in the "
3001                "Ensembl Exon '%u:%S'.\n",
3002                exon->Identifier, exon->Stableidentifier);
3003 
3004         return ajFalse;
3005     }
3006 
3007     /*
3008     ** It is sligtly more efficient, if undefined AJAX String
3009     ** objects are directly allocated by the following functions
3010     ** to their final size.
3011     */
3012 
3013     if ((exon->SequenceCache == NULL) ||
3014         (ajStrGetLen(exon->SequenceCache) == 0))
3015     {
3016         if (!ensSliceIsCircular(slice, &circular))
3017             return ajFalse;
3018 
3019         if (circular == ajTrue)
3020         {
3021             if (ensSliceGetStart(slice) > ensSliceGetEnd(slice))
3022             {
3023                 /*
3024                 ** Normally, Ensembl Exon objects overlapping the chromosome
3025                 ** origin will have a negative Ensembl Feature start, but
3026                 ** the Ensembl Slice will be from 1 to Ensembl Sequence Region
3027                 ** length.
3028                 ** In case the Exon is attached to a Sub-Slice try this ...
3029                 */
3030 
3031                 mpoint
3032                     = ensSliceGetSeqregionLength(slice)
3033                     - ensSliceGetStart(slice)
3034                     + 1;
3035 
3036                 /*
3037                 ** It is sligtly more efficient, if undefined AJAX String
3038                 ** objects are directly allocated by the following functions
3039                 ** to their final size.
3040                 */
3041 
3042                 ensSliceFetchSequenceSubStr(slice,
3043                                             ensFeatureGetStart(feature),
3044                                             mpoint,
3045                                             ensFeatureGetStrand(feature),
3046                                             &sequence1);
3047 
3048                 ensSliceFetchSequenceSubStr(slice,
3049                                             mpoint + 1,
3050                                             ensFeatureGetEnd(feature),
3051                                             ensFeatureGetStrand(feature),
3052                                             &sequence2);
3053 
3054                 if (ensFeatureGetStrand(feature) >= 0)
3055                 {
3056                     ajStrAppendS(&exon->SequenceCache, sequence1);
3057                     ajStrAppendS(&exon->SequenceCache, sequence2);
3058                 }
3059                 else
3060                 {
3061                     ajStrAppendS(&exon->SequenceCache, sequence2);
3062                     ajStrAppendS(&exon->SequenceCache, sequence1);
3063                 }
3064 
3065                 ajStrDel(&sequence1);
3066                 ajStrDel(&sequence2);
3067             }
3068             else if ((ensFeatureGetStart(feature) < 0) ||
3069                      (ensFeatureGetStart(feature) > ensFeatureGetEnd(feature)))
3070             {
3071                 /*
3072                 ** Normally, Ensembl Exon objects overlapping the chromosome
3073                 ** origin will be zero-based, and can have negative start
3074                 ** coordinates. Going via a Sub-Slice converts into
3075                 ** chromosome-based coordinates, i.e it will have start greater
3076                 ** than end.
3077                 */
3078 
3079                 mpoint = ensSliceGetSeqregionLength(slice);
3080 
3081                 /*
3082                 ** It is sligtly more efficient, if undefined AJAX String
3083                 ** objects are directly allocated by the following functions
3084                 ** to their final size.
3085                 */
3086 
3087                 ensSliceFetchSequenceSubStr(slice,
3088                                             ensFeatureGetStart(feature),
3089                                             mpoint,
3090                                             ensFeatureGetStrand(feature),
3091                                             &sequence1);
3092 
3093                 ensSliceFetchSequenceSubStr(slice,
3094                                             1,
3095                                             ensFeatureGetEnd(feature),
3096                                             ensFeatureGetStrand(feature),
3097                                             &sequence2);
3098 
3099                 if (ensFeatureGetStrand(feature) >= 0)
3100                 {
3101                     ajStrAppendS(&exon->SequenceCache, sequence1);
3102                     ajStrAppendS(&exon->SequenceCache, sequence2);
3103                 }
3104                 else
3105                 {
3106                     ajStrAppendS(&exon->SequenceCache, sequence2);
3107                     ajStrAppendS(&exon->SequenceCache, sequence1);
3108                 }
3109 
3110                 ajStrDel(&sequence1);
3111                 ajStrDel(&sequence2);
3112             }
3113             else
3114             {
3115                 /* For Ensembl Exon objects not overlapping the origin. */
3116 
3117                 ensSliceFetchSequenceSubStr(slice,
3118                                             ensFeatureGetStart(feature),
3119                                             ensFeatureGetEnd(feature),
3120                                             ensFeatureGetStrand(feature),
3121                                             &exon->SequenceCache);
3122             }
3123         }
3124         else
3125             ensSliceFetchSequenceSubStr(slice,
3126                                         ensFeatureGetStart(feature),
3127                                         ensFeatureGetEnd(feature),
3128                                         ensFeatureGetStrand(feature),
3129                                         &exon->SequenceCache);
3130     }
3131 
3132     if (*Psequence)
3133         ajStrAssignS(Psequence, exon->SequenceCache);
3134     else
3135         *Psequence = ajStrNewS(exon->SequenceCache);
3136 
3137     return ajTrue;
3138 }
3139 
3140 
3141 
3142 
3143 /* @func ensExonFetchSequenceTranslationSeq ***********************************
3144 **
3145 ** Fetch the sequence of an Ensembl Translation covered by an Ensembl Exon as
3146 ** AJAX Sequence.
3147 **
3148 ** The caller is responsible for deleting the AJAX Sequence.
3149 **
3150 ** @cc Bio::EnsEMBL::Exon:peptide
3151 ** @param [u] exon [EnsPExon] Ensembl Exon
3152 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
3153 ** @param [u] translation [EnsPTranslation] Ensembl Translation
3154 ** @param [wP] Psequence [AjPSeq*] AJAX Sequence object address
3155 **
3156 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3157 **
3158 ** @release 6.4.0
3159 ** @@
3160 ******************************************************************************/
3161 
ensExonFetchSequenceTranslationSeq(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation,AjPSeq * Psequence)3162 AjBool ensExonFetchSequenceTranslationSeq(EnsPExon exon,
3163                                           EnsPTranscript transcript,
3164                                           EnsPTranslation translation,
3165                                           AjPSeq *Psequence)
3166 {
3167     AjPStr name = NULL;
3168     AjPStr sequence = NULL;
3169 
3170     if (!exon)
3171         return ajFalse;
3172 
3173     if (!transcript)
3174         return ajFalse;
3175 
3176     if (!translation)
3177         return ajFalse;
3178 
3179     if (!Psequence)
3180         return ajFalse;
3181 
3182     /*
3183     ** It is sligtly more efficient, if undefined AJAX String objects are
3184     ** directly allocated by the following functions to their final size.
3185     */
3186 
3187     ensExonFetchDisplayidentifier(exon, &name);
3188     ensExonFetchSequenceTranslationStr(exon,
3189                                        transcript,
3190                                        translation,
3191                                        &sequence);
3192 
3193     if (*Psequence)
3194     {
3195         ajSeqClear(*Psequence);
3196 
3197         ajSeqAssignNameS(*Psequence, name);
3198         ajSeqAssignSeqS(*Psequence, sequence);
3199     }
3200     else
3201         *Psequence = ajSeqNewNameS(sequence, name);
3202 
3203     ajStrDel(&name);
3204     ajStrDel(&sequence);
3205 
3206     return ajTrue;
3207 }
3208 
3209 
3210 
3211 
3212 /* @funcstatic exonMergeCoordinates *******************************************
3213 **
3214 ** Merge Ensembl Mapper Result objects if end and start coordinates overlap.
3215 ** If all adjacent Ensembl Mapper Result objects can be merged, this function
3216 ** will delete them from the AJAX List and push a new Ensembl Mapper Result
3217 ** spanning all onto the AJAX List. If a merge is not possible, the AJAX List
3218 ** of Ensembl Mapper Result objects remains unchanged.
3219 **
3220 ** @param [u] mrs [AjPList] AJAX List of Ensembl Mapper Results
3221 **
3222 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3223 **
3224 ** @release 6.4.0
3225 ** @@
3226 ******************************************************************************/
3227 
exonMergeCoordinates(AjPList mrs)3228 static AjBool exonMergeCoordinates(AjPList mrs)
3229 {
3230     ajint lastend = 0;
3231 
3232     AjBool merged = AJTRUE;
3233 
3234     AjIList iter = NULL;
3235 
3236     EnsPMapperresult mr1 = NULL;
3237     EnsPMapperresult mr2 = NULL;
3238 
3239     if (!mrs)
3240         return ajFalse;
3241 
3242     iter = ajListIterNew(mrs);
3243 
3244     while (!ajListIterDone(iter))
3245     {
3246         mr1 = (EnsPMapperresult) ajListIterGet(iter);
3247 
3248         if (ensMapperresultGetType(mr1) != ensEMapperresultTypeCoordinate)
3249             continue;
3250 
3251         lastend = ensMapperresultGetCoordinateEnd(mr1);
3252 
3253         while (!ajListIterDone(iter))
3254         {
3255             mr2 = (EnsPMapperresult) ajListIterGet(iter);
3256 
3257             if (ensMapperresultGetType(mr2) != ensEMapperresultTypeCoordinate)
3258                 continue;
3259 
3260             if ((lastend + 1) >= ensMapperresultGetCoordinateStart(mr2))
3261                 lastend = ensMapperresultGetCoordinateEnd(mr2);
3262             else
3263             {
3264                 merged = ajFalse;
3265 
3266                 break;
3267             }
3268         }
3269 
3270         if (merged == ajFalse)
3271             break;
3272     }
3273 
3274     ajListIterDel(&iter);
3275 
3276     if (merged == ajTrue)
3277     {
3278         /*
3279         ** If all Ensembl Mapper Result objects could be merged successfuly,
3280         ** create a new copy of the first Ensembl Mapper Result and set the
3281         ** end coordinate to the last end. Clear the AJAX List of Ensembl
3282         ** Mapper Result objects and push the new one onto it.
3283         */
3284 
3285         mr2 = ensMapperresultNewCpy(mr1);
3286 
3287         ensMapperresultSetCoordinateEnd(mr2, lastend);
3288 
3289         while (ajListPop(mrs, (void **) &mr1))
3290             ensMapperresultDel(&mr1);
3291 
3292         ajListPushAppend(mrs, (void *) mr2);
3293     }
3294 
3295     return merged;
3296 }
3297 
3298 
3299 
3300 
3301 /* @func ensExonFetchSequenceTranslationStr ***********************************
3302 **
3303 ** Fetch the sequence of an Ensembl Translation covered by an Ensembl Exon as
3304 ** AJAX String.
3305 **
3306 ** The caller is responsible for deleting the AJAX String.
3307 **
3308 ** @cc Bio::EnsEMBL::Exon::peptide
3309 ** @param [u] exon [EnsPExon] Ensembl Exon
3310 ** @param [u] transcript [EnsPTranscript] Ensembl Transcript
3311 ** @param [u] translation [EnsPTranslation] Ensembl Translation
3312 ** @param [wP] Psequence [AjPStr*] AJAX String object address
3313 **
3314 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3315 **
3316 ** @release 6.4.0
3317 ** @@
3318 ******************************************************************************/
3319 
ensExonFetchSequenceTranslationStr(EnsPExon exon,EnsPTranscript transcript,EnsPTranslation translation,AjPStr * Psequence)3320 AjBool ensExonFetchSequenceTranslationStr(EnsPExon exon,
3321                                           EnsPTranscript transcript,
3322                                           EnsPTranslation translation,
3323                                           AjPStr *Psequence)
3324 {
3325     const char *Ptr = NULL;
3326 
3327     register ajint length = 0;
3328 
3329     ajint start = 0;
3330     ajint end   = 0;
3331 
3332     AjIList iter = NULL;
3333 
3334     AjPList mrs = NULL;
3335 
3336     AjPStr sequence = NULL;
3337 
3338     EnsPExon nexon = NULL;
3339 
3340     EnsPFeature tfeature = NULL;
3341 
3342     EnsPMapperresult mr = NULL;
3343 
3344     EnsPSlice tslice = NULL;
3345 
3346     if (!exon)
3347         return ajFalse;
3348 
3349     if (!transcript)
3350         return ajFalse;
3351 
3352     if (!translation)
3353         return ajFalse;
3354 
3355     if (!Psequence)
3356         return ajFalse;
3357 
3358     if (*Psequence)
3359         ajStrAssignClear(Psequence);
3360     else
3361         *Psequence = ajStrNew();
3362 
3363     /* Convert Ensembl Exon coordinates to Ensembl Translation coordinates. */
3364 
3365     tfeature = ensTranscriptGetFeature(transcript);
3366 
3367     tslice = ensFeatureGetSlice(tfeature);
3368 
3369     nexon = ensExonTransfer(exon, tslice);
3370 
3371     if (!nexon)
3372         ajFatal("ensExonFetchSequenceTranslationStr could not transfer "
3373                 "Ensembl Exon to Ensembl Transcript Slice.");
3374 
3375     mrs = ajListNew();
3376 
3377     ensTranscriptMapperSliceTotranslation(transcript,
3378                                           translation,
3379                                           ensFeatureGetStart(nexon->Feature),
3380                                           ensFeatureGetEnd(nexon->Feature),
3381                                           ensFeatureGetStrand(nexon->Feature),
3382                                           mrs);
3383 
3384     /*
3385     ** Filter out Ensembl Mapper Result objects of type
3386     ** ensEMapperresultTypeGap.
3387     */
3388 
3389     iter = ajListIterNew(mrs);
3390 
3391     while (!ajListIterDone(iter))
3392     {
3393         mr = (EnsPMapperresult) ajListIterGet(iter);
3394 
3395         if (ensMapperresultGetType(mr) != ensEMapperresultTypeCoordinate)
3396         {
3397             ajListIterRemove(iter);
3398 
3399             ensMapperresultDel(&mr);
3400         }
3401     }
3402 
3403     ajListIterDel(&iter);
3404 
3405     /* If this is UTR then the peptide will be empty string */
3406 
3407     if (ajListGetLength(mrs) > 1)
3408     {
3409         if (!exonMergeCoordinates(mrs))
3410             ajFatal("ensExonFetchSequenceTranslationStr got an Exon (%u), "
3411                     "which maps to multiple non-continuous locations in the "
3412                     "Ensembl Translation.",
3413                     exon->Identifier);
3414     }
3415     else if (ajListGetLength(mrs) == 1)
3416     {
3417         ajListPeekFirst(mrs, (void **) &mr);
3418 
3419         sequence = ajStrNew();
3420 
3421         ensTranscriptFetchSequenceTranslationStr(transcript,
3422                                                  translation,
3423                                                  &sequence);
3424 
3425         /*
3426         ** NOTE: Since ajStrGetLen returns size_t, which exceeds ajint,
3427         ** the sequence length needs to be determined here.
3428         */
3429 
3430         for (length = 0, Ptr = ajStrGetPtr(sequence);
3431              (Ptr && *Ptr);
3432              length++, Ptr++)
3433             if (length == INT_MAX)
3434                 ajFatal("ensExonFetchSequenceTranslationStr exeeded INT_MAX.");
3435 
3436         end = (ensMapperresultGetCoordinateEnd(mr) > length)
3437             ? length : ensMapperresultGetCoordinateEnd(mr);
3438 
3439         start = (ensMapperresultGetCoordinateStart(mr) < end)
3440             ? ensMapperresultGetCoordinateStart(mr) : end;
3441 
3442         ajStrAssignSubS(Psequence, sequence, start, end);
3443 
3444         ajStrDel(&sequence);
3445     }
3446 
3447     ensExonDel(&nexon);
3448 
3449     return ajTrue;
3450 }
3451 
3452 
3453 
3454 
3455 /* @section matching **********************************************************
3456 **
3457 ** Functions for matching Ensembl Exon objects
3458 **
3459 ** @fdata [EnsPExon]
3460 **
3461 ** @nam3rule Match      Test Ensembl Exon objects for identity
3462 ** @nam3rule Overlap    Test Ensembl Exon objects for overlap
3463 ** @nam3rule Similarity Test Ensembl Exon objects for similarity
3464 **
3465 ** @argrule * exon1 [const EnsPExon] Ensembl Exon
3466 ** @argrule * exon2 [const EnsPExon] Ensembl Exon
3467 **
3468 ** @valrule * [AjBool] True on success
3469 **
3470 ** @fcategory use
3471 ******************************************************************************/
3472 
3473 
3474 
3475 
3476 /* @func ensExonMatch *********************************************************
3477 **
3478 ** Test Ensembl Exon objects for identity.
3479 **
3480 ** @param [r] exon1 [const EnsPExon] Ensembl Exon
3481 ** @param [r] exon2 [const EnsPExon] Ensembl Exon
3482 **
3483 ** @return [AjBool] ajTrue if the Ensembl Exon objects are equal
3484 **
3485 ** @release 6.4.0
3486 ** @@
3487 ** The comparison is based on an initial pointer equality test and if that
3488 ** fails, individual members are compared.
3489 ******************************************************************************/
3490 
ensExonMatch(const EnsPExon exon1,const EnsPExon exon2)3491 AjBool ensExonMatch(const EnsPExon exon1, const EnsPExon exon2)
3492 {
3493     if (!exon1)
3494         return ajFalse;
3495 
3496     if (!exon2)
3497         return ajFalse;
3498 
3499     if (exon1 == exon2)
3500         return ajTrue;
3501 
3502     if (exon1->Identifier != exon2->Identifier)
3503         return ajFalse;
3504 
3505     if (exon1->Adaptor != exon2->Adaptor)
3506         return ajFalse;
3507 
3508     if (!ensFeatureMatch(exon1->Feature, exon2->Feature))
3509         return ajFalse;
3510 
3511     if (exon1->PhaseStart != exon2->PhaseStart)
3512         return ajFalse;
3513 
3514     if (exon1->PhaseEnd != exon2->PhaseEnd)
3515         return ajFalse;
3516 
3517     if (exon1->Current != exon2->Current)
3518         return ajFalse;
3519 
3520     if (exon1->Constitutive != exon2->Constitutive)
3521         return ajFalse;
3522 
3523     /* Stable identifiers are optional. */
3524 
3525     if ((exon1->Stableidentifier || exon2->Stableidentifier)
3526         && (!ajStrMatchS(exon1->Stableidentifier, exon2->Stableidentifier)))
3527         return ajFalse;
3528 
3529     if (exon1->Version != exon2->Version)
3530         return ajFalse;
3531 
3532     /* Creation dates are optional. */
3533 
3534     if ((exon1->DateCreation || exon2->DateCreation)
3535         && (!ajStrMatchS(exon1->DateCreation, exon2->DateCreation)))
3536         return ajFalse;
3537 
3538     /* Modification dates are optional. */
3539 
3540     if ((exon1->DateModification || exon2->DateModification)
3541         && (!ajStrMatchS(exon1->DateModification, exon2->DateModification)))
3542         return ajFalse;
3543 
3544     /*
3545     ** NOTE: The SequenceCache and Supportingfeatures members are currently
3546     ** not checked.
3547     */
3548 
3549     return ajTrue;
3550 }
3551 
3552 
3553 
3554 
3555 /* @func ensExonSimilarity ****************************************************
3556 **
3557 ** Test Ensembl Exon objects for similarity.
3558 **
3559 ** @cc Bio::EnsEMBL::Exon::equals
3560 ** @param [r] exon1 [const EnsPExon] Ensembl Exon
3561 ** @param [r] exon2 [const EnsPExon] Ensembl Exon
3562 **
3563 ** @return [AjBool] ajTrue if the Ensembl Exon objects are similar
3564 **
3565 ** @release 6.4.0
3566 ** @@
3567 ** NOTE: This function is similar to Bio::EnsEMBL::Exon::equals, but not
3568 ** completely identical.
3569 ** The comparison is based on an initial pointer equality test and if that
3570 ** fails, individual members are compared.
3571 ******************************************************************************/
3572 
ensExonSimilarity(const EnsPExon exon1,const EnsPExon exon2)3573 AjBool ensExonSimilarity(const EnsPExon exon1, const EnsPExon exon2)
3574 {
3575     if (!exon1)
3576         return ajFalse;
3577 
3578     if (!exon2)
3579         return ajFalse;
3580 
3581     if (exon1 == exon2)
3582         return ajTrue;
3583 
3584     if (exon1->Identifier != exon2->Identifier)
3585         return ajFalse;
3586 
3587     if (exon1->Adaptor != exon2->Adaptor)
3588         return ajFalse;
3589 
3590     if (!ensFeatureSimilarity(exon1->Feature, exon2->Feature))
3591         return ajFalse;
3592 
3593     if (exon1->PhaseStart != exon2->PhaseStart)
3594         return ajFalse;
3595 
3596     if (exon1->PhaseEnd != exon2->PhaseEnd)
3597         return ajFalse;
3598 
3599     if (exon1->Current != exon2->Current)
3600         return ajFalse;
3601 
3602     if (exon1->Constitutive != exon2->Constitutive)
3603         return ajFalse;
3604 
3605     /* Stable identifiers are optional. */
3606 
3607     if ((exon1->Stableidentifier || exon2->Stableidentifier)
3608         && (!ajStrMatchS(exon1->Stableidentifier, exon2->Stableidentifier)))
3609         return ajFalse;
3610 
3611     if (exon1->Version != exon2->Version)
3612         return ajFalse;
3613 
3614     /* Creation dates are optional. */
3615 
3616     if ((exon1->DateCreation || exon2->DateCreation)
3617         && (!ajStrMatchS(exon1->DateCreation, exon2->DateCreation)))
3618         return ajFalse;
3619 
3620     /* Modification dates are optional. */
3621 
3622     if ((exon1->DateModification || exon2->DateModification)
3623         && (!ajStrMatchS(exon1->DateModification, exon2->DateModification)))
3624         return ajFalse;
3625 
3626     /*
3627     ** NOTE: The SequenceCache and Supportingfeatures members are currently
3628     ** not checked.
3629     */
3630 
3631     return ajTrue;
3632 }
3633 
3634 
3635 
3636 
3637 /* @datasection [AjPList] AJAX List *******************************************
3638 **
3639 ** @nam2rule List Functions for manipulating AJAX List objects
3640 **
3641 ******************************************************************************/
3642 
3643 
3644 
3645 
3646 /* @funcstatic listExonCompareEndAscending ************************************
3647 **
3648 ** AJAX List of Ensembl Exon objects comparison function to sort by
3649 ** Ensembl Feature end coordinate in ascending order.
3650 **
3651 ** @param [r] item1 [const void*] Ensembl Exon address 1
3652 ** @param [r] item2 [const void*] Ensembl Exon address 2
3653 ** @see ajListSort
3654 **
3655 ** @return [int] The comparison function returns an integer less than,
3656 **               equal to, or greater than zero if the first argument is
3657 **               considered to be respectively less than, equal to, or
3658 **               greater than the second.
3659 **
3660 ** @release 6.4.0
3661 ** @@
3662 ******************************************************************************/
3663 
listExonCompareEndAscending(const void * item1,const void * item2)3664 static int listExonCompareEndAscending(
3665     const void *item1,
3666     const void *item2)
3667 {
3668     EnsPExon exon1 = *(EnsOExon *const *) item1;
3669     EnsPExon exon2 = *(EnsOExon *const *) item2;
3670 
3671 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3672     if (ajDebugTest("listExonCompareEndAscending"))
3673         ajDebug("listExonCompareEndAscending\n"
3674                 "  exon1 %p\n"
3675                 "  exon2 %p\n",
3676                 exon1,
3677                 exon2);
3678 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3679 
3680     /* Sort empty values towards the end of the AJAX List. */
3681 
3682     if (exon1 && (!exon2))
3683         return -1;
3684 
3685     if ((!exon1) && (!exon2))
3686         return 0;
3687 
3688     if ((!exon1) && exon2)
3689         return +1;
3690 
3691     return ensFeatureCompareEndAscending(exon1->Feature, exon2->Feature);
3692 }
3693 
3694 
3695 
3696 
3697 /* @funcstatic listExonCompareEndDescending ***********************************
3698 **
3699 ** AJAX List of Ensembl Exon objects comparison function to sort by
3700 ** Ensembl Feature end coordinate in descending order.
3701 **
3702 ** @param [r] item1 [const void*] Ensembl Exon address 1
3703 ** @param [r] item2 [const void*] Ensembl Exon address 2
3704 ** @see ajListSort
3705 **
3706 ** @return [int] The comparison function returns an integer less than,
3707 **               equal to, or greater than zero if the first argument is
3708 **               considered to be respectively less than, equal to, or
3709 **               greater than the second.
3710 **
3711 ** @release 6.4.0
3712 ** @@
3713 ******************************************************************************/
3714 
listExonCompareEndDescending(const void * item1,const void * item2)3715 static int listExonCompareEndDescending(
3716     const void *item1,
3717     const void *item2)
3718 {
3719     EnsPExon exon1 = *(EnsOExon *const *) item1;
3720     EnsPExon exon2 = *(EnsOExon *const *) item2;
3721 
3722 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3723     if (ajDebugTest("listExonCompareEndDescending"))
3724         ajDebug("listExonCompareEndDescending\n"
3725                 "  exon1 %p\n"
3726                 "  exon2 %p\n",
3727                 exon1,
3728                 exon2);
3729 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3730 
3731     /* Sort empty values towards the end of the AJAX List. */
3732 
3733     if (exon1 && (!exon2))
3734         return -1;
3735 
3736     if ((!exon1) && (!exon2))
3737         return 0;
3738 
3739     if ((!exon1) && exon2)
3740         return +1;
3741 
3742     return ensFeatureCompareEndDescending(exon1->Feature, exon2->Feature);
3743 }
3744 
3745 
3746 
3747 
3748 /* @funcstatic listExonCompareIdentifierAscending *****************************
3749 **
3750 ** AJAX List of Ensembl Exon objects comparison function to sort by
3751 ** identifier in ascending order.
3752 **
3753 ** @param [r] item1 [const void*] Ensembl Exon address 1
3754 ** @param [r] item2 [const void*] Ensembl Exon address 2
3755 ** @see ajListSort
3756 **
3757 ** @return [int] The comparison function returns an integer less than,
3758 **               equal to, or greater than zero if the first argument is
3759 **               considered to be respectively less than, equal to, or
3760 **               greater than the second.
3761 **
3762 ** @release 6.4.0
3763 ** @@
3764 ******************************************************************************/
3765 
listExonCompareIdentifierAscending(const void * item1,const void * item2)3766 static int listExonCompareIdentifierAscending(
3767     const void *item1,
3768     const void *item2)
3769 {
3770     EnsPExon exon1 = *(EnsOExon *const *) item1;
3771     EnsPExon exon2 = *(EnsOExon *const *) item2;
3772 
3773 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3774     if (ajDebugTest("listExonCompareIdentifierAscending"))
3775         ajDebug("listExonCompareIdentifierAscending\n"
3776                 "  exon1 %p\n"
3777                 "  exon2 %p\n",
3778                 exon1,
3779                 exon2);
3780 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3781 
3782     /* Sort empty values towards the end of the AJAX List. */
3783 
3784     if (exon1 && (!exon2))
3785         return -1;
3786 
3787     if ((!exon1) && (!exon2))
3788         return 0;
3789 
3790     if ((!exon1) && exon2)
3791         return +1;
3792 
3793     if (exon1->Identifier < exon2->Identifier)
3794         return -1;
3795 
3796     if (exon1->Identifier > exon2->Identifier)
3797         return +1;
3798 
3799     return 0;
3800 }
3801 
3802 
3803 
3804 
3805 /* @funcstatic listExonCompareStartAscending **********************************
3806 **
3807 ** AJAX List of Ensembl Exon objects comparison function to sort by
3808 ** Ensembl Feature start coordinate in ascending order.
3809 **
3810 ** @param [r] item1 [const void*] Ensembl Exon address 1
3811 ** @param [r] item2 [const void*] Ensembl Exon address 2
3812 ** @see ajListSort
3813 **
3814 ** @return [int] The comparison function returns an integer less than,
3815 **               equal to, or greater than zero if the first argument is
3816 **               considered to be respectively less than, equal to, or
3817 **               greater than the second.
3818 **
3819 ** @release 6.4.0
3820 ** @@
3821 ******************************************************************************/
3822 
listExonCompareStartAscending(const void * item1,const void * item2)3823 static int listExonCompareStartAscending(
3824     const void *item1,
3825     const void *item2)
3826 {
3827     EnsPExon exon1 = *(EnsOExon *const *) item1;
3828     EnsPExon exon2 = *(EnsOExon *const *) item2;
3829 
3830 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3831     if (ajDebugTest("listExonCompareStartAscending"))
3832         ajDebug("listExonCompareStartAscending\n"
3833                 "  exon1 %p\n"
3834                 "  exon2 %p\n",
3835                 exon1,
3836                 exon2);
3837 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3838 
3839     /* Sort empty values towards the end of the AJAX List. */
3840 
3841     if (exon1 && (!exon2))
3842         return -1;
3843 
3844     if ((!exon1) && (!exon2))
3845         return 0;
3846 
3847     if ((!exon1) && exon2)
3848         return +1;
3849 
3850     return ensFeatureCompareStartAscending(exon1->Feature, exon2->Feature);
3851 }
3852 
3853 
3854 
3855 
3856 /* @funcstatic listExonCompareStartDescending *********************************
3857 **
3858 ** AJAX List of Ensembl Exon objects comparison function to sort by
3859 ** Ensembl Feature start coordinate in descending order.
3860 **
3861 ** @param [r] item1 [const void*] Ensembl Exon address 1
3862 ** @param [r] item2 [const void*] Ensembl Exon address 2
3863 ** @see ajListSort
3864 **
3865 ** @return [int] The comparison function returns an integer less than,
3866 **               equal to, or greater than zero if the first argument is
3867 **               considered to be respectively less than, equal to, or
3868 **               greater than the second.
3869 **
3870 ** @release 6.4.0
3871 ** @@
3872 ******************************************************************************/
3873 
listExonCompareStartDescending(const void * item1,const void * item2)3874 static int listExonCompareStartDescending(
3875     const void *item1,
3876     const void *item2)
3877 {
3878     EnsPExon exon1 = *(EnsOExon *const *) item1;
3879     EnsPExon exon2 = *(EnsOExon *const *) item2;
3880 
3881 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
3882     if (ajDebugTest("listExonCompareStartDescending"))
3883         ajDebug("listExonCompareStartDescending\n"
3884                 "  exon1 %p\n"
3885                 "  exon2 %p\n",
3886                 exon1,
3887                 exon2);
3888 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
3889 
3890     /* Sort empty values towards the end of the AJAX List. */
3891 
3892     if (exon1 && (!exon2))
3893         return -1;
3894 
3895     if ((!exon1) && (!exon2))
3896         return 0;
3897 
3898     if ((!exon1) && exon2)
3899         return +1;
3900 
3901     return ensFeatureCompareStartDescending(exon1->Feature, exon2->Feature);
3902 }
3903 
3904 
3905 
3906 
3907 /* @section list **************************************************************
3908 **
3909 ** Functions for manipulating AJAX List objects.
3910 **
3911 ** @fdata [AjPList]
3912 **
3913 ** @nam3rule Exon Functions for manipulating AJAX List objects of
3914 ** Ensembl Exon objects
3915 ** @nam4rule Sort       Sort functions
3916 ** @nam5rule End        Sort by Ensembl Feature end member
3917 ** @nam5rule Identifier Sort by Ensembl Exon identifier member
3918 ** @nam5rule Start      Sort by Ensembl Feature start member
3919 ** @nam6rule Ascending  Sort in ascending order
3920 ** @nam6rule Descending Sort in descending order
3921 **
3922 ** @argrule * exons [AjPList] AJAX List of Ensembl Exon objects
3923 **
3924 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
3925 **
3926 ** @fcategory misc
3927 ******************************************************************************/
3928 
3929 
3930 
3931 
3932 /* @func ensListExonSortEndAscending ******************************************
3933 **
3934 ** Sort an AJAX List of Ensembl Exon objects by their
3935 ** Ensembl Feature end coordinate in ascending order.
3936 **
3937 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
3938 **
3939 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3940 **
3941 ** @release 6.4.0
3942 ** @@
3943 ******************************************************************************/
3944 
ensListExonSortEndAscending(AjPList exons)3945 AjBool ensListExonSortEndAscending(AjPList exons)
3946 {
3947     if (!exons)
3948         return ajFalse;
3949 
3950     ajListSortTwoThree(exons,
3951                        &listExonCompareEndAscending,
3952                        &listExonCompareStartAscending,
3953                        &listExonCompareIdentifierAscending);
3954 
3955     return ajTrue;
3956 }
3957 
3958 
3959 
3960 
3961 /* @func ensListExonSortEndDescending *****************************************
3962 **
3963 ** Sort an AJAX List of Ensembl Exon objects by their
3964 ** Ensembl Feature end coordinate in descending order.
3965 **
3966 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
3967 **
3968 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3969 **
3970 ** @release 6.4.0
3971 ** @@
3972 ******************************************************************************/
3973 
ensListExonSortEndDescending(AjPList exons)3974 AjBool ensListExonSortEndDescending(AjPList exons)
3975 {
3976     if (!exons)
3977         return ajFalse;
3978 
3979     ajListSortTwoThree(exons,
3980                        &listExonCompareEndDescending,
3981                        &listExonCompareStartDescending,
3982                        &listExonCompareIdentifierAscending);
3983 
3984     return ajTrue;
3985 }
3986 
3987 
3988 
3989 
3990 /* @func ensListExonSortIdentifierAscending ***********************************
3991 **
3992 ** Sort an AJAX List of Ensembl Exon objects by their
3993 ** identifier in ascending order.
3994 **
3995 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
3996 **
3997 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
3998 **
3999 ** @release 6.4.0
4000 ** @@
4001 ******************************************************************************/
4002 
ensListExonSortIdentifierAscending(AjPList exons)4003 AjBool ensListExonSortIdentifierAscending(AjPList exons)
4004 {
4005     if (!exons)
4006         return ajFalse;
4007 
4008     ajListSort(exons, &listExonCompareIdentifierAscending);
4009 
4010     return ajTrue;
4011 }
4012 
4013 
4014 
4015 
4016 /* @func ensListExonSortStartAscending ****************************************
4017 **
4018 ** Sort an AJAX List of Ensembl Exon objects by their
4019 ** Ensembl Feature start coordinate in ascending order.
4020 **
4021 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4022 **
4023 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4024 **
4025 ** @release 6.4.0
4026 ** @@
4027 ******************************************************************************/
4028 
ensListExonSortStartAscending(AjPList exons)4029 AjBool ensListExonSortStartAscending(AjPList exons)
4030 {
4031     if (!exons)
4032         return ajFalse;
4033 
4034     ajListSortTwoThree(exons,
4035                        &listExonCompareStartAscending,
4036                        &listExonCompareEndAscending,
4037                        &listExonCompareIdentifierAscending);
4038 
4039     return ajTrue;
4040 }
4041 
4042 
4043 
4044 
4045 /* @func ensListExonSortStartDescending ***************************************
4046 **
4047 ** Sort an AJAX List of Ensembl Exon objects by their
4048 ** Ensembl Feature start coordinate in descending order.
4049 **
4050 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4051 **
4052 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4053 **
4054 ** @release 6.4.0
4055 ** @@
4056 ******************************************************************************/
4057 
ensListExonSortStartDescending(AjPList exons)4058 AjBool ensListExonSortStartDescending(AjPList exons)
4059 {
4060     if (!exons)
4061         return ajFalse;
4062 
4063     ajListSortTwoThree(exons,
4064                        &listExonCompareStartDescending,
4065                        &listExonCompareEndDescending,
4066                        &listExonCompareIdentifierAscending);
4067 
4068     return ajTrue;
4069 }
4070 
4071 
4072 
4073 
4074 /* @datasection [AjPSeq] AJAX Sequence ****************************************
4075 **
4076 ** @nam2rule Sequence Functions for manipulating AJAX Sequence objects
4077 **
4078 ******************************************************************************/
4079 
4080 
4081 
4082 
4083 /* @section add ***************************************************************
4084 **
4085 ** Functions for manipulating AJAX Sequence objects.
4086 **
4087 ** @fdata [AjPSeq]
4088 **
4089 ** @nam3rule Add Add to an AJAX Sequence
4090 ** @nam4rule Feature Add an AJAX Feature
4091 ** @nam5rule Exon Convert an Ensembl Exon into an AJAX Feature
4092 **
4093 ** @argrule * seq [AjPSeq] AJAX Sequence
4094 ** @argrule Exon exon [EnsPExon] Ensembl Exon
4095 ** @argrule Exon rank [ajint] Rank in an Ensembl Transcript
4096 ** @argrule Exon Pfeature [AjPFeature*] AJAX Feature address
4097 **
4098 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
4099 **
4100 ** @fcategory misc
4101 ******************************************************************************/
4102 
4103 
4104 
4105 
4106 /* @func ensSequenceAddFeatureExon ********************************************
4107 **
4108 ** Convert an Ensembl Exon into an AJAX Feature and add it to the
4109 ** AJAX Feature Table of an AJAX Sequence.
4110 **
4111 ** @param [u] seq [AjPSeq] AJAX Sequence
4112 ** @param [u] exon [EnsPExon] Ensembl Exon
4113 ** @param [rN] rank [ajint] Rank in an Ensembl Transcript
4114 ** @param [wP] Pfeature [AjPFeature*] AJAX Feature address
4115 **
4116 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4117 **
4118 ** @release 6.5.0
4119 ** @@
4120 ******************************************************************************/
4121 
ensSequenceAddFeatureExon(AjPSeq seq,EnsPExon exon,ajint rank,AjPFeature * Pfeature)4122 AjBool ensSequenceAddFeatureExon(AjPSeq seq,
4123                                  EnsPExon exon,
4124                                  ajint rank,
4125                                  AjPFeature *Pfeature)
4126 {
4127     AjPStr label = NULL;
4128     AjPStr type  = NULL;
4129 
4130     EnsPDatabaseadaptor dba = NULL;
4131 
4132     EnsPExon newexon = NULL;
4133 
4134     EnsPSlice slice      = NULL;
4135     EnsPSliceadaptor sla = NULL;
4136 
4137     if (!seq)
4138         return ajFalse;
4139 
4140     if (!exon)
4141         return ajFalse;
4142 
4143     if (!Pfeature)
4144         return ajFalse;
4145 
4146     *Pfeature = NULL;
4147 
4148     /*
4149     ** NOTE: An AJAX Sequence accessor function returning the
4150     ** AJAX Feature Table in modifiable form is missing.
4151     */
4152 
4153     if (!seq->Fttable)
4154         return ajFalse;
4155 
4156     /*
4157     ** Get the Ensembl Slice covering the AJAX Sequence object and transfer
4158     ** the Ensembl Exon object onto it.
4159     */
4160 
4161     dba = ensExonadaptorGetDatabaseadaptor(exon->Adaptor);
4162 
4163     sla = ensRegistryGetSliceadaptor(dba);
4164 
4165     ensSliceadaptorFetchByName(sla, ajSeqGetNameS(seq), &slice);
4166 
4167     if (!slice)
4168     {
4169         ajDebug("ensSequenceAddFeatureExon could not fetch an "
4170                 "Ensembl Slice for AJAX Sequence name '%S'.\n",
4171                 ajSeqGetNameS(seq));
4172 
4173         return ajFalse;
4174     }
4175 
4176     newexon = ensExonTransfer(exon, slice);
4177 
4178     if (!newexon)
4179     {
4180         ajDebug("ensSequenceAddFeatureExon could not transfer "
4181                 "Ensembl Exon %p onto "
4182                 "Ensembl Slice %p.\n", exon, slice);
4183 
4184         ensExonTrace(exon, 1);
4185         ensSliceTrace(slice, 1);
4186 
4187         ensSliceDel(&slice);
4188 
4189         return ajFalse;
4190     }
4191 
4192     /* Convert the Ensembl Exon into an AJAX Feature. */
4193 
4194     type = ajStrNewC("exon");
4195 
4196     *Pfeature = ajFeatNewNucFlags(
4197         seq->Fttable,
4198         ensAnalysisGetName(ensFeatureGetAnalysis(newexon->Feature)),
4199         type,
4200         ensFeatureGetStart(newexon->Feature),
4201         ensFeatureGetEnd(newexon->Feature),
4202         0.0F,
4203         ensFeatureCalculateStrand(newexon->Feature),
4204         ensExonCalculateFrame(newexon),
4205         rank,
4206         0, /* Start 2 */
4207         0, /* End 2 */
4208         (AjPStr) NULL, /* Remote Identifier */
4209         (AjPStr) NULL, /* Label */
4210         0);
4211 
4212     ensExonFetchDisplayidentifier(newexon, &label);
4213 
4214     ajFeatTagAddCS(*Pfeature, "standard_name", label);
4215 
4216     ajStrDel(&label);
4217     ajStrDel(&type);
4218 
4219     ensExonDel(&newexon);
4220 
4221     ensSliceDel(&slice);
4222 
4223     return ajTrue;
4224 }
4225 
4226 
4227 
4228 
4229 /* @datasection [EnsPExonadaptor] Ensembl Exon Adaptor ************************
4230 **
4231 ** @nam2rule Exonadaptor Functions for manipulating
4232 ** Ensembl Exon Adaptor objects
4233 **
4234 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor
4235 ** @cc CVS Revision: 1.121
4236 ** @cc CVS Tag: branch-ensembl-68
4237 **
4238 ******************************************************************************/
4239 
4240 
4241 
4242 
4243 /* @funcstatic exonadaptorFetchAllbyStatement *********************************
4244 **
4245 ** Fetch all Ensembl Exon objects via an SQL statement.
4246 **
4247 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::_objs_from_sth
4248 ** @param [u] ba [EnsPBaseadaptor] Ensembl Base Adaptor
4249 ** @param [r] statement [const AjPStr] SQL statement
4250 ** @param [uN] am [EnsPAssemblymapper] Ensembl Assembly Mapper
4251 ** @param [uN] slice [EnsPSlice] Ensembl Slice
4252 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4253 **
4254 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4255 **
4256 ** @release 6.4.0
4257 ** @@
4258 ******************************************************************************/
4259 
exonadaptorFetchAllbyStatement(EnsPBaseadaptor ba,const AjPStr statement,EnsPAssemblymapper am,EnsPSlice slice,AjPList exons)4260 static AjBool exonadaptorFetchAllbyStatement(
4261     EnsPBaseadaptor ba,
4262     const AjPStr statement,
4263     EnsPAssemblymapper am,
4264     EnsPSlice slice,
4265     AjPList exons)
4266 {
4267     ajint sphase = 0;
4268     ajint ephase = 0;
4269 
4270     ajuint identifier = 0U;
4271     ajuint version    = 0U;
4272 
4273     ajuint srid     = 0U;
4274     ajuint srstart  = 0U;
4275     ajuint srend    = 0U;
4276     ajint  srstrand = 0;
4277 
4278     AjBool current      = AJFALSE;
4279     AjBool constitutive = AJFALSE;
4280 
4281     AjPSqlstatement sqls = NULL;
4282     AjISqlrow sqli       = NULL;
4283     AjPSqlrow sqlr       = NULL;
4284 
4285     AjPStr stableid = NULL;
4286     AjPStr cdate    = NULL;
4287     AjPStr mdate    = NULL;
4288 
4289     EnsPDatabaseadaptor dba = NULL;
4290 
4291     EnsPExon exon      = NULL;
4292     EnsPExonadaptor ea = NULL;
4293 
4294     EnsPFeature feature = NULL;
4295 
4296     if (ajDebugTest("exonadaptorFetchAllbyStatement"))
4297         ajDebug("exonadaptorFetchAllbyStatement\n"
4298                 "  ba %p\n"
4299                 "  statement %p\n"
4300                 "  am %p\n"
4301                 "  slice %p\n"
4302                 "  exons %p\n",
4303                 ba,
4304                 statement,
4305                 am,
4306                 slice,
4307                 exons);
4308 
4309     if (!ba)
4310         return ajFalse;
4311 
4312     if (!statement)
4313         return ajFalse;
4314 
4315     if (!exons)
4316         return ajFalse;
4317 
4318     dba = ensBaseadaptorGetDatabaseadaptor(ba);
4319 
4320     ea  = ensRegistryGetExonadaptor(dba);
4321 
4322     sqls = ensDatabaseadaptorSqlstatementNew(dba, statement);
4323 
4324     sqli = ajSqlrowiterNew(sqls);
4325 
4326     while (!ajSqlrowiterDone(sqli))
4327     {
4328         identifier   = 0;
4329         srid         = 0U;
4330         srstart      = 0U;
4331         srend        = 0U;
4332         srstrand     = 0;
4333         sphase       = 0;
4334         ephase       = 0;
4335         current      = ajFalse;
4336         constitutive = ajFalse;
4337         stableid     = ajStrNew();
4338         version      = 0U;
4339         cdate        = ajStrNew();
4340         mdate        = ajStrNew();
4341 
4342         sqlr = ajSqlrowiterGet(sqli);
4343 
4344         ajSqlcolumnToUint(sqlr, &identifier);
4345         ajSqlcolumnToUint(sqlr, &srid);
4346         ajSqlcolumnToUint(sqlr, &srstart);
4347         ajSqlcolumnToUint(sqlr, &srend);
4348         ajSqlcolumnToInt(sqlr, &srstrand);
4349         ajSqlcolumnToInt(sqlr, &sphase);
4350         ajSqlcolumnToInt(sqlr, &ephase);
4351         ajSqlcolumnToBool(sqlr, &current);
4352         ajSqlcolumnToBool(sqlr, &constitutive);
4353         ajSqlcolumnToStr(sqlr, &stableid);
4354         ajSqlcolumnToUint(sqlr, &version);
4355         ajSqlcolumnToStr(sqlr, &cdate);
4356         ajSqlcolumnToStr(sqlr, &mdate);
4357 
4358         ensBaseadaptorRetrieveFeature(ba,
4359                                       0U,
4360                                       srid,
4361                                       srstart,
4362                                       srend,
4363                                       srstrand,
4364                                       am,
4365                                       slice,
4366                                       &feature);
4367 
4368         if (!feature)
4369         {
4370             ajStrDel(&stableid);
4371             ajStrDel(&cdate);
4372             ajStrDel(&mdate);
4373 
4374             continue;
4375         }
4376 
4377         /* Finally, create a new Ensembl Exon. */
4378 
4379         exon = ensExonNewIni(ea,
4380                              identifier,
4381                              feature,
4382                              sphase,
4383                              ephase,
4384                              current,
4385                              constitutive,
4386                              stableid,
4387                              version,
4388                              cdate,
4389                              mdate);
4390 
4391         ajListPushAppend(exons, (void *) exon);
4392 
4393         ensFeatureDel(&feature);
4394 
4395         ajStrDel(&stableid);
4396         ajStrDel(&cdate);
4397         ajStrDel(&mdate);
4398     }
4399 
4400     ajSqlrowiterDel(&sqli);
4401 
4402     ensDatabaseadaptorSqlstatementDel(dba, &sqls);
4403 
4404     return ajTrue;
4405 }
4406 
4407 
4408 
4409 
4410 /* @section constructors ******************************************************
4411 **
4412 ** All constructors return a new Ensembl Exon Adaptor by pointer.
4413 ** It is the responsibility of the user to first destroy any previous
4414 ** Exon Adaptor. The target pointer does not need to be initialised to
4415 ** NULL, but it is good programming practice to do so anyway.
4416 **
4417 ** @fdata [EnsPExonadaptor]
4418 **
4419 ** @nam3rule New Constructor
4420 **
4421 ** @argrule New dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
4422 **
4423 ** @valrule * [EnsPExonadaptor] Ensembl Exon Adaptor or NULL
4424 **
4425 ** @fcategory new
4426 ******************************************************************************/
4427 
4428 
4429 
4430 
4431 /* @func ensExonadaptorNew ****************************************************
4432 **
4433 ** Default constructor for an Ensembl Exon Adaptor.
4434 **
4435 ** Ensembl Object Adaptors are singleton objects in the sense that a single
4436 ** instance of an Ensembl Object Adaptor connected to a particular database is
4437 ** sufficient to instantiate any number of Ensembl Objects from the database.
4438 ** Each Ensembl Object will have a weak reference to the Object Adaptor that
4439 ** instantiated it. Therefore, Ensembl Object Adaptors should not be
4440 ** instantiated directly, but rather obtained from the Ensembl Registry,
4441 ** which will in turn call this function if neccessary.
4442 **
4443 ** @see ensRegistryGetDatabaseadaptor
4444 ** @see ensRegistryGetExonadaptor
4445 **
4446 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::new
4447 ** @param [u] dba [EnsPDatabaseadaptor] Ensembl Database Adaptor
4448 **
4449 ** @return [EnsPExonadaptor] Ensembl Exon Adaptor or NULL
4450 **
4451 ** @release 6.2.0
4452 ** @@
4453 ******************************************************************************/
4454 
ensExonadaptorNew(EnsPDatabaseadaptor dba)4455 EnsPExonadaptor ensExonadaptorNew(
4456     EnsPDatabaseadaptor dba)
4457 {
4458     EnsPExonadaptor ea = NULL;
4459 
4460     if (!dba)
4461         return NULL;
4462 
4463     AJNEW0(ea);
4464 
4465     ea->Exonadaptor = ensFeatureadaptorNew(
4466         dba,
4467         exonadaptorKTablenames,
4468         exonadaptorKColumnnames,
4469         (const EnsPBaseadaptorLeftjoin) NULL,
4470         (const char *) NULL,
4471         (const char *) NULL,
4472         &exonadaptorFetchAllbyStatement,
4473         (void *(*)(const void *)) NULL,
4474         (void *(*)(void *)) &ensExonNewRef,
4475         (AjBool (*)(const void *)) NULL,
4476         (void (*)(void **)) &ensExonDel,
4477         (size_t (*)(const void *)) &ensExonCalculateMemsize,
4478         (EnsPFeature (*)(const void *)) &ensExonGetFeature,
4479         "Exon");
4480 
4481     ea->Exontranscriptadaptor = ensFeatureadaptorNew(
4482         dba,
4483         exontranscriptadaptorKTablenames,
4484         exonadaptorKColumnnames,
4485         (const EnsPBaseadaptorLeftjoin) NULL,
4486         exontranscriptadaptorKDefaultcondition,
4487         exontranscriptadaptorKFinalcondition,
4488         &exonadaptorFetchAllbyStatement,
4489         (void *(*)(const void *)) NULL,
4490         (void *(*)(void *)) &ensExonNewRef,
4491         (AjBool (*)(const void *)) NULL,
4492         (void (*)(void **)) &ensExonDel,
4493         (size_t (*)(const void *)) &ensExonCalculateMemsize,
4494         (EnsPFeature (*)(const void *)) &ensExonGetFeature,
4495         "Exontranscript");
4496 
4497     return ea;
4498 }
4499 
4500 
4501 
4502 
4503 /* @section destructors *******************************************************
4504 **
4505 ** Destruction destroys all internal data structures and frees the memory
4506 ** allocated for an Ensembl Exon Adaptor object.
4507 **
4508 ** @fdata [EnsPExonadaptor]
4509 **
4510 ** @nam3rule Del Destroy (free) an Ensembl Exon Adaptor
4511 **
4512 ** @argrule * Pea [EnsPExonadaptor*] Ensembl Exon Adaptor address
4513 **
4514 ** @valrule * [void]
4515 **
4516 ** @fcategory delete
4517 ******************************************************************************/
4518 
4519 
4520 
4521 
4522 /* @func ensExonadaptorDel ****************************************************
4523 **
4524 ** Default destructor for an Ensembl Exon Adaptor.
4525 **
4526 ** Ensembl Object Adaptors are singleton objects that are registered in the
4527 ** Ensembl Registry and weakly referenced by Ensembl Objects that have been
4528 ** instantiated by it. Therefore, Ensembl Object Adaptors should never be
4529 ** destroyed directly. Upon exit, the Ensembl Registry will call this function
4530 ** if required.
4531 **
4532 ** @param [d] Pea [EnsPExonadaptor*] Ensembl Exon Adaptor address
4533 **
4534 ** @return [void]
4535 **
4536 ** @release 6.2.0
4537 ** @@
4538 ******************************************************************************/
4539 
ensExonadaptorDel(EnsPExonadaptor * Pea)4540 void ensExonadaptorDel(EnsPExonadaptor *Pea)
4541 {
4542     EnsPExonadaptor pthis = NULL;
4543 
4544     if (!Pea)
4545         return;
4546 
4547 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
4548     if (ajDebugTest("ensExonadaptorDel"))
4549         ajDebug("ensExonadaptorDel\n"
4550                 "  *Pea %p\n",
4551                 *Pea);
4552 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
4553 
4554     if (!(pthis = *Pea))
4555         return;
4556 
4557     ensFeatureadaptorDel(&pthis->Exonadaptor);
4558     ensFeatureadaptorDel(&pthis->Exontranscriptadaptor);
4559 
4560     ajMemFree((void **) Pea);
4561 
4562     return;
4563 }
4564 
4565 
4566 
4567 
4568 /* @section member retrieval **************************************************
4569 **
4570 ** Functions for returning members of an Ensembl Exon Adaptor object.
4571 **
4572 ** @fdata [EnsPExonadaptor]
4573 **
4574 ** @nam3rule Get Return Ensembl Exon Adaptor attribute(s)
4575 ** @nam4rule Baseadaptor Return the Ensembl Base Adaptor
4576 ** @nam4rule Featureadaptor Return the Ensembl Feature Adaptor
4577 ** @nam4rule Databaseadaptor Return the Ensembl Database Adaptor
4578 **
4579 ** @argrule * ea [EnsPExonadaptor] Ensembl Exon Adaptor
4580 **
4581 ** @valrule Baseadaptor [EnsPBaseadaptor]
4582 ** Ensembl Base Adaptor or NULL
4583 ** @valrule Featureadaptor [EnsPFeatureadaptor]
4584 ** Ensembl Feature Adaptor or NULL
4585 ** @valrule Databaseadaptor [EnsPDatabaseadaptor]
4586 ** Ensembl Database Adaptor or NULL
4587 **
4588 ** @fcategory use
4589 ******************************************************************************/
4590 
4591 
4592 
4593 
4594 /* @func ensExonadaptorGetBaseadaptor *****************************************
4595 **
4596 ** Get the Ensembl Base Adaptor member of the
4597 ** Ensembl Feature Adaptor member of an Ensembl Exon Adaptor.
4598 **
4599 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4600 **
4601 ** @return [EnsPBaseadaptor] Ensembl Base Adaptor or NULL
4602 **
4603 ** @release 6.2.0
4604 ** @@
4605 ******************************************************************************/
4606 
ensExonadaptorGetBaseadaptor(EnsPExonadaptor ea)4607 EnsPBaseadaptor ensExonadaptorGetBaseadaptor(EnsPExonadaptor ea)
4608 {
4609     return (ea) ? ensFeatureadaptorGetBaseadaptor(ea->Exonadaptor) : NULL;
4610 }
4611 
4612 
4613 
4614 
4615 /* @func ensExonadaptorGetDatabaseadaptor *************************************
4616 **
4617 ** Get the Ensembl Database Adaptor member of the
4618 ** Ensembl Feature Adaptor member of an Ensembl Exon Adaptor.
4619 **
4620 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4621 **
4622 ** @return [EnsPDatabaseadaptor] Ensembl Database Adaptor
4623 **
4624 ** @release 6.2.0
4625 ** @@
4626 ******************************************************************************/
4627 
ensExonadaptorGetDatabaseadaptor(EnsPExonadaptor ea)4628 EnsPDatabaseadaptor ensExonadaptorGetDatabaseadaptor(EnsPExonadaptor ea)
4629 {
4630     return (ea) ? ensFeatureadaptorGetDatabaseadaptor(ea->Exonadaptor) : NULL;
4631 }
4632 
4633 
4634 
4635 
4636 /* @func ensExonadaptorGetFeatureadaptor **************************************
4637 **
4638 ** Get the Ensembl Feature Adaptor member of an Ensembl Exon Adaptor.
4639 **
4640 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4641 **
4642 ** @return [EnsPFeatureadaptor] Ensembl Feature Adaptor
4643 **
4644 ** @release 6.2.0
4645 ** @@
4646 ******************************************************************************/
4647 
ensExonadaptorGetFeatureadaptor(EnsPExonadaptor ea)4648 EnsPFeatureadaptor ensExonadaptorGetFeatureadaptor(EnsPExonadaptor ea)
4649 {
4650     return (ea) ? ea->Exonadaptor : NULL;
4651 }
4652 
4653 
4654 
4655 
4656 /* @section canonical object retrieval ****************************************
4657 **
4658 ** Functions for fetching Ensembl Exon objects from an
4659 ** Ensembl SQL database.
4660 **
4661 ** @fdata [EnsPExonadaptor]
4662 **
4663 ** @nam3rule Fetch Fetch Ensembl Exon object(s)
4664 ** @nam4rule All   Fetch all Ensembl Exon objects
4665 ** @nam4rule Allby Fetch all Ensembl Exon objects matching a criterion
4666 ** @nam5rule Slice Fetch all by an Ensembl Slice
4667 ** @nam5rule Stableidentifier Fetch all by a stable identifier
4668 ** @nam5rule Transcript       Fetch all by an Ensembl Transcript
4669 ** @nam4rule By    Fetch one Ensembl Exon object matching a criterion
4670 ** @nam5rule Identifier       Fetch by SQL database-internal identifier
4671 ** @nam5rule Stableidentifier Fetch by a stable identifier
4672 **
4673 ** @argrule * ea [EnsPExonadaptor] Ensembl Exon Adaptor
4674 ** @argrule All exons [AjPList] AJAX List of Ensembl Exon objects
4675 ** @argrule AllbySlice slice [EnsPSlice] Ensembl Slice
4676 ** @argrule AllbySlice constraint [const AjPStr] SQL constraint
4677 ** @argrule AllbyStableidentifier stableid [const AjPStr] Stable identifier
4678 ** @argrule AllbyTranscript transcript [const EnsPTranscript]
4679 ** Ensembl Transcript
4680 ** @argrule Allby exons [AjPList] AJAX List of Ensembl Exon objects
4681 ** @argrule ByIdentifier identifier [ajuint] SQL database-internal identifier
4682 ** @argrule ByStableidentifier stableid [const AjPStr] Stable identifier
4683 ** @argrule ByStableidentifier version [ajuint] Version
4684 ** @argrule By Pexon [EnsPExon*] Ensembl Exon address
4685 **
4686 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
4687 **
4688 ** @fcategory use
4689 ******************************************************************************/
4690 
4691 
4692 
4693 
4694 /* @func ensExonadaptorFetchAll ***********************************************
4695 **
4696 ** Fetch all Ensembl Exon objects.
4697 **
4698 ** The caller is responsible for deleting the Ensembl Exon objects before
4699 ** deleting the AJAX List.
4700 **
4701 ** @cc Bio::EnsEMBL::DBSQL::BaseAdaptor::fetch_all
4702 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4703 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4704 **
4705 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4706 **
4707 ** @release 6.2.0
4708 ** @@
4709 ******************************************************************************/
4710 
ensExonadaptorFetchAll(EnsPExonadaptor ea,AjPList exons)4711 AjBool ensExonadaptorFetchAll(EnsPExonadaptor ea,
4712                               AjPList exons)
4713 {
4714     AjBool result = AJFALSE;
4715 
4716     AjPStr constraint = NULL;
4717 
4718     if (!ea)
4719         return ajFalse;
4720 
4721     if (!exons)
4722         return ajFalse;
4723 
4724     constraint = ajStrNewC("exon.is_current = 1");
4725 
4726     result = ensBaseadaptorFetchAllbyConstraint(
4727         ensExonadaptorGetBaseadaptor(ea),
4728         constraint,
4729         (EnsPAssemblymapper) NULL,
4730         (EnsPSlice) NULL,
4731         exons);
4732 
4733     ajStrDel(&constraint);
4734 
4735     return result;
4736 }
4737 
4738 
4739 
4740 
4741 /* @func ensExonadaptorFetchAllbySlice ****************************************
4742 **
4743 ** Fetch all Ensembl Exon objects matching a SQL constraint on an
4744 ** Ensembl Slice.
4745 **
4746 ** The caller is responsible for deleting the Ensembl Exon objects before
4747 ** deleting the AJAX List.
4748 **
4749 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_Slice
4750 ** @cc Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor::fetch_all_by_Slice_constraint
4751 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4752 ** @param [u] slice [EnsPSlice] Ensembl Slice
4753 ** @param [rN] constraint [const AjPStr] SQL constraint
4754 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4755 **
4756 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4757 **
4758 ** @release 6.4.0
4759 ** @@
4760 ******************************************************************************/
4761 
ensExonadaptorFetchAllbySlice(EnsPExonadaptor ea,EnsPSlice slice,const AjPStr constraint,AjPList exons)4762 AjBool ensExonadaptorFetchAllbySlice(EnsPExonadaptor ea,
4763                                      EnsPSlice slice,
4764                                      const AjPStr constraint,
4765                                      AjPList exons)
4766 {
4767     if (!ea)
4768         return ajFalse;
4769 
4770     if (!slice)
4771         return ajFalse;
4772 
4773     if (!exons)
4774         return ajFalse;
4775 
4776     return ensFeatureadaptorFetchAllbySlice(
4777         ensExonadaptorGetFeatureadaptor(ea),
4778         slice,
4779         constraint,
4780         (AjPStr) NULL,
4781         exons);
4782 }
4783 
4784 
4785 
4786 
4787 /* @func ensExonadaptorFetchAllbyStableidentifier *****************************
4788 **
4789 ** Fetch all Ensembl Exon versions via a stable identifier.
4790 **
4791 ** The caller is responsible for deleting the Ensembl Exon objects before
4792 ** deleting the AJAX List.
4793 **
4794 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::fetch_all_versions_by_stable_id
4795 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4796 ** @param [r] stableid [const AjPStr] Stable identifier
4797 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4798 **
4799 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4800 **
4801 ** @release 6.4.0
4802 ** @@
4803 ******************************************************************************/
4804 
ensExonadaptorFetchAllbyStableidentifier(EnsPExonadaptor ea,const AjPStr stableid,AjPList exons)4805 AjBool ensExonadaptorFetchAllbyStableidentifier(EnsPExonadaptor ea,
4806                                                 const AjPStr stableid,
4807                                                 AjPList exons)
4808 {
4809     char *txtstableid = NULL;
4810 
4811     AjBool result = AJFALSE;
4812 
4813     AjPStr constraint = NULL;
4814 
4815     EnsPBaseadaptor ba = NULL;
4816 
4817     if (!ea)
4818         return ajFalse;
4819 
4820     if (!stableid)
4821         return ajFalse;
4822 
4823     if (!exons)
4824         return ajFalse;
4825 
4826     ba = ensExonadaptorGetBaseadaptor(ea);
4827 
4828     ensBaseadaptorEscapeC(ba, &txtstableid, stableid);
4829 
4830     constraint = ajFmtStr("exon.stable_id = '%s'", txtstableid);
4831 
4832     ajCharDel(&txtstableid);
4833 
4834     result = ensBaseadaptorFetchAllbyConstraint(
4835         ba,
4836         constraint,
4837         (EnsPAssemblymapper) NULL,
4838         (EnsPSlice) NULL,
4839         exons);
4840 
4841     ajStrDel(&constraint);
4842 
4843     return result;
4844 }
4845 
4846 
4847 
4848 
4849 /* @func ensExonadaptorFetchAllbyTranscript ***********************************
4850 **
4851 ** Fetch all Ensembl Exon objects via an Ensembl Transcript.
4852 **
4853 ** The caller is responsible for deleting the Ensembl Exon objects before
4854 ** deleting the AJAX List.
4855 **
4856 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::fetch_all_by_Transcript
4857 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4858 ** @param [r] transcript [const EnsPTranscript] Ensembl Transcript
4859 ** @param [u] exons [AjPList] AJAX List of Ensembl Exon objects
4860 **
4861 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
4862 **
4863 ** @release 6.4.0
4864 ** @@
4865 ******************************************************************************/
4866 
ensExonadaptorFetchAllbyTranscript(EnsPExonadaptor ea,const EnsPTranscript transcript,AjPList exons)4867 AjBool ensExonadaptorFetchAllbyTranscript(EnsPExonadaptor ea,
4868                                           const EnsPTranscript transcript,
4869                                           AjPList exons)
4870 {
4871     AjBool circular = AJFALSE;
4872     AjBool result   = AJFALSE;
4873 
4874     AjIList iter = NULL;
4875 
4876     AjPStr constraint = NULL;
4877 
4878     EnsPExon exon = NULL;
4879 
4880     EnsPFeature efeature = NULL;
4881     EnsPFeature tfeature = NULL;
4882 
4883     EnsPSlice eslice = NULL;
4884     EnsPSlice tslice = NULL;
4885 
4886     if (ajDebugTest("ensExonadaptorFetchAllbyTranscript"))
4887     {
4888         ajDebug("ensExonadaptorFetchAllbyTranscript\n"
4889                 "  ea %p\n"
4890                 "  transcript %p\n"
4891                 "  exons %p\n",
4892                 ea,
4893                 transcript,
4894                 exons);
4895 
4896         ensTranscriptTrace(transcript, 1);
4897     }
4898 
4899     if (!ea)
4900         return ajFalse;
4901 
4902     if (!transcript)
4903         return ajFalse;
4904 
4905     if (!exons)
4906         return ajFalse;
4907 
4908     tfeature = ensTranscriptGetFeature(transcript);
4909 
4910     tslice = ensFeatureGetSlice(tfeature);
4911 
4912     if (!tslice)
4913     {
4914         ajDebug("ensExonadaptorFetchAllbyTranscript cannot fetch Exon objects "
4915                 "for an Ensembl Transcript without an Ensembl Slice.\n");
4916 
4917         return ajFalse;
4918     }
4919 
4920     if (ensSliceIsCircular(tslice, &circular) == ajFalse)
4921         return ajFalse;
4922 
4923     if (circular == ajTrue)
4924         eslice = ensSliceNewRef(tslice);
4925     else
4926     {
4927         /*
4928         ** For Transcript objects on linear Slice objects fetch a Slice that
4929         ** spans just this Transcript for placing Exon objects.
4930         */
4931 
4932         ensSliceadaptorFetchByFeature(
4933             ensRegistryGetSliceadaptor(ensExonadaptorGetDatabaseadaptor(ea)),
4934             tfeature,
4935             0,
4936             &eslice);
4937     }
4938 
4939     /*
4940     ** Use the Exon Transcript Adaptor, which has the "exon_transcript" SQL
4941     ** table joined permanently via a default SQL condition.
4942     */
4943 
4944     constraint = ajFmtStr(
4945         "exon_transcript.transcript_id = %u",
4946         ensTranscriptGetIdentifier(transcript));
4947 
4948     result = ensFeatureadaptorFetchAllbySlice(
4949         ea->Exontranscriptadaptor,
4950         eslice,
4951         constraint,
4952         (const AjPStr) NULL,
4953         exons);
4954 
4955     /*
4956     ** Remap Exon coordinates if neccessary.
4957     ** NOTE: Ensembl Exon objects are fetched on an Ensembl Slice, which spans
4958     ** only the Ensembl Transcript, to work with haplotypes (HAPs) and
4959     ** pseudo-autosomal regions (PARs).
4960     */
4961 
4962     if (!ensSliceMatch(eslice, tslice))
4963     {
4964         iter = ajListIterNew(exons);
4965 
4966         while (!ajListIterDone(iter))
4967         {
4968             exon = (EnsPExon) ajListIterGet(iter);
4969 
4970             efeature = ensFeatureTransfer(exon->Feature, tslice);
4971 
4972             ensExonSetFeature(exon, efeature);
4973 
4974             ensFeatureDel(&efeature);
4975         }
4976 
4977         ajListIterDel(&iter);
4978     }
4979 
4980     ajStrDel(&constraint);
4981 
4982     ensSliceDel(&eslice);
4983 
4984     return result;
4985 }
4986 
4987 
4988 
4989 
4990 /* @func ensExonadaptorFetchByIdentifier **************************************
4991 **
4992 ** Fetch an Ensembl Exon via its SQL database-internal identifier.
4993 **
4994 ** The caller is responsible for deleting the Ensembl Exon.
4995 **
4996 ** @cc Bio::EnsEMBL::DBSQL::BaseAdaptor::fetch_by_dbID
4997 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
4998 ** @param [r] identifier [ajuint] SQL database-internal identifier
4999 ** @param [wP] Pexon [EnsPExon*] Ensembl Exon address
5000 **
5001 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5002 **
5003 ** @release 6.2.0
5004 ** @@
5005 ******************************************************************************/
5006 
ensExonadaptorFetchByIdentifier(EnsPExonadaptor ea,ajuint identifier,EnsPExon * Pexon)5007 AjBool ensExonadaptorFetchByIdentifier(EnsPExonadaptor ea,
5008                                        ajuint identifier,
5009                                        EnsPExon *Pexon)
5010 {
5011     return ensBaseadaptorFetchByIdentifier(
5012         ensExonadaptorGetBaseadaptor(ea),
5013         identifier,
5014         (void **) Pexon);
5015 }
5016 
5017 
5018 
5019 
5020 /* @func ensExonadaptorFetchByStableidentifier ********************************
5021 **
5022 ** Fetch an Ensembl Exon via its stable identifier and version.
5023 ** In case a particular version is not specified,
5024 ** the current Exon will be returned.
5025 **
5026 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::fetch_by_stable_id
5027 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
5028 ** @param [r] stableid [const AjPStr] Stable identifier
5029 ** @param [r] version [ajuint] Version
5030 ** @param [wP] Pexon [EnsPExon*] Ensembl Exon address
5031 **
5032 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5033 **
5034 ** @release 6.4.0
5035 ** @@
5036 ******************************************************************************/
5037 
ensExonadaptorFetchByStableidentifier(EnsPExonadaptor ea,const AjPStr stableid,ajuint version,EnsPExon * Pexon)5038 AjBool ensExonadaptorFetchByStableidentifier(EnsPExonadaptor ea,
5039                                              const AjPStr stableid,
5040                                              ajuint version,
5041                                              EnsPExon *Pexon)
5042 {
5043     char *txtstableid = NULL;
5044 
5045     AjBool result = AJFALSE;
5046 
5047     AjPList exons = NULL;
5048 
5049     AjPStr constraint = NULL;
5050 
5051     EnsPBaseadaptor ba = NULL;
5052 
5053     EnsPExon exon = NULL;
5054 
5055     if (!ea)
5056         return ajFalse;
5057 
5058     if (!stableid)
5059         return ajFalse;
5060 
5061     if (!Pexon)
5062         return ajFalse;
5063 
5064     *Pexon = NULL;
5065 
5066     ba = ensExonadaptorGetBaseadaptor(ea);
5067 
5068     ensBaseadaptorEscapeC(ba, &txtstableid, stableid);
5069 
5070     if (version)
5071         constraint = ajFmtStr(
5072             "exon.stable_id = '%s' "
5073             "AND "
5074             "exon.version = %u",
5075             txtstableid,
5076             version);
5077     else
5078         constraint = ajFmtStr(
5079             "exon.stable_id = '%s' "
5080             "AND "
5081             "exon.is_current = 1",
5082             txtstableid);
5083 
5084     ajCharDel(&txtstableid);
5085 
5086     exons = ajListNew();
5087 
5088     result = ensBaseadaptorFetchAllbyConstraint(
5089         ba,
5090         constraint,
5091         (EnsPAssemblymapper) NULL,
5092         (EnsPSlice) NULL,
5093         exons);
5094 
5095     if (ajListGetLength(exons) > 1)
5096         ajDebug("ensExonadaptorFetchByStableId got more than one "
5097                 "Ensembl Exon for stable identifier '%S' and version %u.\n",
5098                 stableid, version);
5099 
5100     ajListPop(exons, (void **) Pexon);
5101 
5102     while (ajListPop(exons, (void **) &exon))
5103         ensExonDel(&exon);
5104 
5105     ajListFree(&exons);
5106 
5107     ajStrDel(&constraint);
5108 
5109     return result;
5110 }
5111 
5112 
5113 
5114 
5115 /* @section accessory object retrieval ****************************************
5116 **
5117 ** Functions for retrieving objects releated to Ensembl Exon objects from an
5118 ** Ensembl SQL database.
5119 **
5120 ** @fdata [EnsPExonadaptor]
5121 **
5122 ** @nam3rule Retrieve Retrieve Ensembl Exon-releated object(s)
5123 ** @nam4rule All Retrieve all Ensembl Exon-releated objects
5124 ** @nam5rule Identifiers Retrieve all SQL database-internal identifier objects
5125 ** @nam5rule Stableidentifiers Retrieve all stable identifier objects
5126 **
5127 ** @argrule * ea [EnsPExonadaptor] Ensembl Exon Adaptor
5128 ** @argrule AllIdentifiers identifiers [AjPList]
5129 ** AJAX List of AJAX unsigned integer (Ensembl Exon identifier) objects
5130 ** @argrule AllStableidentifiers stableids [AjPList]
5131 ** AJAX List of AJAX String (Ensembl Exon stable identifier) objects
5132 **
5133 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
5134 **
5135 ** @fcategory use
5136 ******************************************************************************/
5137 
5138 
5139 
5140 
5141 /* @func ensExonadaptorRetrieveAllIdentifiers *********************************
5142 **
5143 ** Retrieve all SQL database-internal identifier objects of
5144 ** Ensembl Exon objects.
5145 **
5146 ** The caller is responsible for deleting the AJAX unsigned integer objects
5147 ** before deleting the AJAX List.
5148 **
5149 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::list_dbIDs
5150 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
5151 ** @param [u] identifiers [AjPList]
5152 ** AJAX List of AJAX unsigned integer (Ensembl Exon identifier) objects
5153 **
5154 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5155 **
5156 ** @release 6.4.0
5157 ** @@
5158 ******************************************************************************/
5159 
ensExonadaptorRetrieveAllIdentifiers(EnsPExonadaptor ea,AjPList identifiers)5160 AjBool ensExonadaptorRetrieveAllIdentifiers(EnsPExonadaptor ea,
5161                                             AjPList identifiers)
5162 {
5163     AjBool result = AJFALSE;
5164 
5165     AjPStr table = NULL;
5166 
5167     if (!ea)
5168         return ajFalse;
5169 
5170     if (!identifiers)
5171         return ajFalse;
5172 
5173     table = ajStrNewC("exon");
5174 
5175     result = ensBaseadaptorRetrieveAllIdentifiers(
5176         ensExonadaptorGetBaseadaptor(ea),
5177         table,
5178         (AjPStr) NULL,
5179         identifiers);
5180 
5181     ajStrDel(&table);
5182 
5183     return result;
5184 }
5185 
5186 
5187 
5188 
5189 /* @func ensExonadaptorRetrieveAllStableidentifiers ***************************
5190 **
5191 ** Retrieve all stable identifiers of Ensembl Exon objects.
5192 **
5193 ** The caller is responsible for deleting the AJAX String objects
5194 ** before deleting the AJAX List.
5195 **
5196 ** @cc Bio::EnsEMBL::DBSQL::ExonAdaptor::list_stable_ids
5197 ** @param [u] ea [EnsPExonadaptor] Ensembl Exon Adaptor
5198 ** @param [u] stableids [AjPList]
5199 ** AJAX List of AJAX String (Ensembl Exon stable identifier) objects
5200 **
5201 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
5202 **
5203 ** @release 6.4.0
5204 ** @@
5205 ******************************************************************************/
5206 
ensExonadaptorRetrieveAllStableidentifiers(EnsPExonadaptor ea,AjPList stableids)5207 AjBool ensExonadaptorRetrieveAllStableidentifiers(EnsPExonadaptor ea,
5208                                                   AjPList stableids)
5209 {
5210     AjBool result = AJFALSE;
5211 
5212     AjPStr table   = NULL;
5213     AjPStr primary = NULL;
5214 
5215     if (!ea)
5216         return ajFalse;
5217 
5218     if (!stableids)
5219         return ajFalse;
5220 
5221     table   = ajStrNewC("exon");
5222     primary = ajStrNewC("stable_id");
5223 
5224     result = ensBaseadaptorRetrieveAllStrings(
5225         ensExonadaptorGetBaseadaptor(ea),
5226         table,
5227         primary,
5228         stableids);
5229 
5230     ajStrDel(&table);
5231     ajStrDel(&primary);
5232 
5233     return result;
5234 }
5235