DataflowRule.pm 8.97 KB
Newer Older
1
=pod
2 3

=head1 NAME
Jessica Severin's avatar
Jessica Severin committed
4

5
    Bio::EnsEMBL::Hive::DataflowRule
6 7

=head1 DESCRIPTION
Jessica Severin's avatar
Jessica Severin committed
8

9
    A data container object (methods are intelligent getters/setters) that corresponds to a row stored in 'dataflow_rule' table:
10

11
    CREATE TABLE dataflow_rule (
12
        dataflow_rule_id    int(10) unsigned NOT NULL AUTO_INCREMENT,
13 14
        from_analysis_id    int(10) unsigned NOT NULL,
        branch_code         int(10) default 1 NOT NULL,
15
        funnel_dataflow_rule_id  int(10) unsigned default NULL,
16
        to_analysis_url     varchar(255) default '' NOT NULL,
17
        input_id_template   TEXT DEFAULT NULL,
Jessica Severin's avatar
Jessica Severin committed
18

19 20 21 22
        PRIMARY KEY (dataflow_rule_id),
        UNIQUE (from_analysis_id, to_analysis_url)
    );

Leo Gordon's avatar
Leo Gordon committed
23
    A dataflow rule is activated when a Bio::EnsEMBL::Hive::AnalysisJob::dataflow_output_id is called at any moment during a RunnableDB's execution.
24 25 26
    The current RunnableDB's analysis ($from_analysis) and the requested $branch_code (1 by default) define the entry conditions,
    and whatever rules match these conditions will generate new jobs with input_ids specified in the dataflow_output_id() call.
    If input_id_template happens to contain a non-NULL value, it will be used to generate the corresponding intput_id instead.
27

28
    Jessica's remark on the structure of to_analysis_url:
29
        Extended from design of SimpleRule concept to allow the 'to' analysis to be specified with a network savy URL like
30
        mysql://ensadmin:<pass>@ecs2:3361/compara_hive_test/analysis?logic_name='blast_NCBI34'
31

32 33
=head1 LICENSE

34
    Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
35 36 37 38 39 40 41 42 43 44

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License
    is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and limitations under the License.

45
=head1 CONTACT
Jessica Severin's avatar
Jessica Severin committed
46

47
    Please subscribe to the Hive mailing list:  http://listserver.ebi.ac.uk/mailman/listinfo/ehive-users  to discuss Hive-related questions or to be notified of our updates
48 49 50 51 52 53 54

=cut


package Bio::EnsEMBL::Hive::DataflowRule;

use strict;
55

56 57 58 59
use Bio::EnsEMBL::Utils::Argument ('rearrange');
use Bio::EnsEMBL::Utils::Exception ('throw');

use Bio::EnsEMBL::Hive::Utils ('stringify');
Leo Gordon's avatar
Leo Gordon committed
60
use Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor;
61

62 63 64 65
use base (  'Bio::EnsEMBL::Storable',       # inherit dbID(), adaptor() and new() methods
         );


66
=head2 new
67

68
  Usage   : Bio::EnsEMBL::Hive::DataflowRule->new(-from_analysis => $fromAnalysis, -to_analysis => $toAnalysis, -branch_code => $branch_code);
69
  Function: Constructor for DataflowRule object
Jessica Severin's avatar
Jessica Severin committed
70
  Returns : Bio::EnsEMBL::Hive::DataflowRule
71
  Args    : a rearrange-compatible hash
Jessica Severin's avatar
Jessica Severin committed
72
            
73 74 75
=cut

sub new {
76 77
    my $class = shift @_;

78
    my $self = $class->SUPER::new( @_ );    # deal with Storable stuff
79

80 81
    my ($fromAnalysis, $toAnalysis, $from_analysis_id, $branch_code, $funnel_dataflow_rule_id, $to_analysis_url, $input_id_template ) =
    rearrange( [ qw (FROM_ANALYSIS TO_ANALYSIS FROM_ANALYSIS_ID BRANCH_CODE FUNNEL_DATAFLOW_RULE_ID TO_ANALYSIS_URL INPUT_ID_TEMPLATE) ], @_ );
82 83 84 85 86 87

        # from objects:
    $self->from_analysis( $fromAnalysis )           if(defined($fromAnalysis));
    $self->to_analysis( $toAnalysis )               if(defined($toAnalysis));

        # simple scalars:
88 89 90
    $self->from_analysis_id($from_analysis_id)      if(defined($from_analysis_id));
    $self->to_analysis_url($to_analysis_url)        if(defined($to_analysis_url));
    $self->branch_code($branch_code)                if(defined($branch_code));
91
    $self->funnel_dataflow_rule_id($funnel_dataflow_rule_id)  if(defined($funnel_dataflow_rule_id));
92 93 94
    $self->input_id_template($input_id_template)    if(defined($input_id_template));

    return $self;
95 96
}

97

98
=head2 branch_code
Jessica Severin's avatar
Jessica Severin committed
99

100 101
    Function: getter/setter method for the branch_code of the dataflow rule

102
=cut
Jessica Severin's avatar
Jessica Severin committed
103

104
sub branch_code {
105 106
    my $self = shift @_;

107 108 109
    if(@_) {
        my $branch_name_or_code = shift @_;
        $self->{'_branch_code'} = $branch_name_or_code && Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor::branch_name_2_code( $branch_name_or_code );
110
    }
111
    return $self->{'_branch_code'};
112 113
}

114

115
=head2 funnel_dataflow_rule_id
116

117
    Function: getter/setter method for the funnel_dataflow_rule_id of the dataflow rule
118 119 120

=cut

121
sub funnel_dataflow_rule_id {
122 123 124
    my $self = shift @_;

    if(@_) { # setter mode
125
        $self->{'_funnel_dataflow_rule_id'} = shift @_;
126
    }
127
    return $self->{'_funnel_dataflow_rule_id'};
128 129
}

130

131 132 133 134 135 136 137 138 139
=head2 input_id_template

    Function: getter/setter method for the input_id_template of the dataflow rule

=cut

sub input_id_template {
    my $self = shift @_;

140
    if(@_) {
141 142
        my $input_id_template = shift @_;
        $self->{'_input_id_template'} = (ref($input_id_template) ? stringify($input_id_template) : $input_id_template),
143 144 145
    }
    return $self->{'_input_id_template'};
}
146

147

148
=head2 from_analysis_id
Jessica Severin's avatar
Jessica Severin committed
149

150 151 152 153
  Arg[1]  : (optional) int $dbID
  Usage   : $self->from_analysis_id($dbID);
  Function: Get/set method for the 'from' analysis objects dbID of this rule.
  Returns : integer
Jessica Severin's avatar
Jessica Severin committed
154
  
155
=cut
Jessica Severin's avatar
Jessica Severin committed
156

157 158 159 160 161 162 163 164 165 166 167
sub from_analysis_id {
  my ($self,$analysis_id) = @_;
  if($analysis_id) {
    $self->{'_from_analysis_id'} = $analysis_id;
    $self->{'_from_analysis'} = undef;
  }
  return $self->{'_from_analysis_id'};
}


=head2 to_analysis_url
Jessica Severin's avatar
Jessica Severin committed
168

169 170 171 172
  Arg[1]  : (optional) string $url
  Usage   : $self->to_analysis_url($url);
  Function: Get/set method for the 'to' analysis objects URL for this rule
  Returns : string
Jessica Severin's avatar
Jessica Severin committed
173
  
174
=cut
Jessica Severin's avatar
Jessica Severin committed
175

176 177 178 179 180 181 182 183 184 185 186
sub to_analysis_url {
  my ($self,$url) = @_;
  if($url) {
    $self->{'_to_analysis_url'} = $url;
    $self->{'_to_analysis'} = undef;
  }
  return $self->{'_to_analysis_url'};
}


=head2 from_analysis
Jessica Severin's avatar
Jessica Severin committed
187

188
  Usage   : $self->from_analysis($analysis);
189
  Function: Get/set method for the condition analysis object of this rule.
190 191
  Returns : Bio::EnsEMBL::Hive::Analysis
  Args    : Bio::EnsEMBL::Hive::Analysis
Jessica Severin's avatar
Jessica Severin committed
192
  
193
=cut
Jessica Severin's avatar
Jessica Severin committed
194

195 196 197 198 199
sub from_analysis {
  my ($self,$analysis) = @_;

  # setter mode
  if( defined $analysis ) {
200
    unless ($analysis->isa('Bio::EnsEMBL::Hive::Analysis')) {
201
      throw(
202
        "from_analysis arg must be a [Bio::EnsEMBL::Hive::Analysis]".
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
        "not a [$analysis]");
    }
    $self->{'_from_analysis'} = $analysis;
    $self->{'_from_analysis_id'} = $analysis->dbID;
  }
  
  # lazy load the analysis object if I can
  if(!defined($self->{'_from_analysis'})
     and defined($self->from_analysis_id)
     and defined($self->adaptor))
  {
    $self->{'_from_analysis'} =
      $self->adaptor->db->get_AnalysisAdaptor->fetch_by_dbID($self->from_analysis_id);
  }
  return $self->{'_from_analysis'};
}


=head2 to_analysis
Jessica Severin's avatar
Jessica Severin committed
222

223
  Usage   : $self->to_analysis($analysis);
224
  Function: Get/set method for the goal analysis object of this rule.
225 226
  Returns : Bio::EnsEMBL::Hive::Analysis
  Args    : Bio::EnsEMBL::Hive::Analysis
Jessica Severin's avatar
Jessica Severin committed
227
  
228
=cut
Jessica Severin's avatar
Jessica Severin committed
229

230
sub to_analysis {
231
  my ($self, $analysis_or_nt) = @_;
232

233 234 235
  if( defined $analysis_or_nt ) {
    unless ($analysis_or_nt->can('url')) {
      throw( "to_analysis arg must support 'url' method, '$analysis_or_nt' does not know how to do it");
236
    }
237
    $self->{'_to_analysis'} = $analysis_or_nt;
Jessica Severin's avatar
Jessica Severin committed
238 239 240

    #if the 'from' and 'to' share the same adaptor, then use a simple logic_name
    #for the URL rather than a full network distributed URL
241

Leo Gordon's avatar
Leo Gordon committed
242
    my $ref_rule_adaptor = $self->from_analysis && $self->from_analysis->adaptor;
243

Leo Gordon's avatar
Leo Gordon committed
244
    if($analysis_or_nt->can('logic_name') and $ref_rule_adaptor and ($ref_rule_adaptor == $analysis_or_nt->adaptor)) {
245
      $self->{'_to_analysis_url'} = $analysis_or_nt->logic_name;
246
    } else {
247
      $self->{'_to_analysis_url'} = $analysis_or_nt->url($ref_rule_adaptor->db);
248
    }
249 250 251
  }
  # lazy load the analysis object if I can
  if(!defined($self->{'_to_analysis'}) and defined($self->to_analysis_url)) {
252

Leo Gordon's avatar
Leo Gordon committed
253 254 255 256 257 258
    my $url = $self->to_analysis_url;

    $self->{'_to_analysis'} = $self->adaptor
        ?  $self->adaptor->db->get_AnalysisAdaptor->fetch_by_logic_name_or_url($url)
        :  Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor->fetch_by_logic_name_or_url($url)
    or die "Cannot fetch analysis from logic_name or url '$url' for dataflow rule with id='".$self->dbID."'\n";
259

260 261 262 263
  }
  return $self->{'_to_analysis'};
}

264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288

=head2 toString

  Args       : (none)
  Example    : print $df_rule->toString()."\n";
  Description: returns a stringified representation of the rule
  Returntype : string

=cut

sub toString {
    my $self = shift;

    return join('',
            'DataflowRule(dbID=',
            ($self->dbID || '?'),
            ($self->funnel_dataflow_rule_id ? ' --|| '.$self->funnel_dataflow_rule_id : ''),
            '): [#',
            $self->branch_code,
            '] ',
            $self->from_analysis->logic_name,
            ' -> ',
            $self->to_analysis_url,
            ($self->input_id_template ? (' WITH TEMPLATE: '.$self->input_id_template) : ''),
    );
289 290
}

291

292 293
1;