File Coverage

blib/lib/SlideMap.pm
Criterion Covered Total %
statement 180 341 52.7
branch 56 122 45.9
condition 15 48 31.2
subroutine 25 37 67.5
pod 0 35 0.0
total 276 583 47.3


line stmt bran cond sub pod time code
1             ####################################################################
2             # Copyright @ 2002 Joseph A. White and The Institute for Genomic
3             # Research (TIGR)
4             # All rights reserved.
5             ####################################################################
6             package SlideMap;
7              
8             require 5.005_02;
9 1     1   680 use strict;
  1         2  
  1         49  
10             #use warnings;
11 1     1   6 use vars qw(@ISA @EXPORT %EXPORT_TAGS @EXPORT_OK $VERSION);
  1         2  
  1         4315  
12              
13             require Exporter;
14              
15             @ISA = qw(Exporter);
16              
17             # Items to export into callers namespace by default. Note: do not export
18             # names by default without a very good reason. Use EXPORT_OK instead.
19             # Do not simply export all your public functions/methods/constants.
20              
21             # This allows declaration use SlideMap ':all';
22             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
23             # will save memory.
24             %EXPORT_TAGS = ( 'all' => [ qw() ] );
25              
26             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27              
28             @EXPORT = qw();
29              
30             $VERSION = '1.4';
31              
32              
33             # Preloaded methods go here.
34              
35             package SlideMap;
36             my %defaults;
37             {
38             ## set default values in case user neglects to do so; use old CT-72 format
39             %defaults = (machine => 'IAS', x_pin => 2, y_pin => 6, x_spacing => 24,
40             y_spacing => 25, x_repeat => 1, y_repeat => 1, x_pitch => 0,
41             y_pitch => 0, num_spots => 0);
42             }
43              
44             package SlideMap;
45             sub new {
46 1     1 0 63 my $class = shift;
47 1         12 my %args = (%defaults, @_);
48              
49             my $self = bless {
50             # print head dimensions
51             _x_pin => int($args{x_pin}),
52             _y_pin => int($args{y_pin}),
53             # block dimensions (in spots)
54             _xspacing => int($args{x_spacing}),
55             _yspacing => int($args{y_spacing}),
56             # for future use; define the spacing in micrometers
57             _x_pitch => int($args{x_pitch}),
58             _y_pitch => int($args{y_pitch}),
59             # microtitre plate dimensions (in wells)
60             _max_plate_row => 0,
61             _max_plate_col => 0,
62             # no. of dips in x (row) dimension
63             _max_xpass => 0,
64             # no. of dips in y (col) dimension
65             _max_ypass => 0,
66             # total # of dips per plate
67             _pass_plate => 0,
68             # number of wells per plate
69             _num_wells => 0,
70             # total number of spots on slide; default 0
71             _num_spots => int($args{num_spots}),,
72             # absolute array dimensions
73             _max_row => 0,
74             _max_col => 0,
75             # total number of plates to fill array
76             _num_plates => 0,
77             # print order (labels for plates)
78             _plates => [],
79             # 1 => 96-well, 2=> 384-well
80             _format => 1,
81             # 0 => normal mode, 1 => repeat mode; for MD/MD3
82             _repeat => 0,
83             # number repeated blocks; 1 => none, 2 => 2 reps, etc.
84             _x_repeat => int($args{x_repeat}),
85             _y_repeat => int($args{y_repeat}),
86             # 0 => top->bottom printing, 1 => left->right printing
87             _print_dir => 0,
88             # 0 => (1,1)->B1 (IAS 12-pen mode), 1 => (1,1)->A1
89             _nocomplement => 0,
90             _machine => $args{machine},
91             # the slide map (row,col,plate,well)
92             _map => [],
93             # for Lucidia printer
94             _paramA => 0,
95             _paramB => 0,
96             _convert_well => {},
97             _convert_spot => {},
98             _test => $args{test}
99            
100 1         22 }, $class;
101            
102 1 50       11 if($args{machine} eq 'MD3') {
    50          
    50          
    50          
    50          
103 0         0 $self->{_format} = 2;
104 0         0 $self->{_print_dir} = 1;
105 0         0 $self->{_x_repeat} = 2;
106 0         0 $self->{_x_repeat} = 1;
107 0         0 $self->{_xspacing} = 32;
108 0         0 $self->{_x_pin} = 1;
109 0         0 $self->{_y_pin} = 12;
110 0         0 $self->{_nocomplement} = 1;
111 0 0       0 if($self->{_yspacing} > 12) { $self->{_yspacing} = 12; }
  0         0  
112             } elsif($args{machine} eq 'Lucidia') {
113 0         0 $self->{_format} = 2;
114 0         0 $self->{_print_dir} = 1;
115 0         0 $self->{_x_pin} = 2;
116 0         0 $self->{_y_pin} = 12;
117             } elsif($args{machine} eq 'Stanford') {
118 0         0 $self->{_format} = 2;
119 0         0 $self->{_print_dir} = 0;
120 0         0 $self->{_x_pin} = 4;
121 0         0 $self->{_y_pin} = 4;
122 0         0 $self->{_nocomplement} = 0;
123             } elsif($args{machine} eq 'MD') {
124 0         0 $self->{_x_repeat} = 2;
125 0         0 $self->{_x_repeat} = 1;
126 0         0 $self->{_yspacing} = 16;
127 0         0 $self->{_x_pin} = 1;
128 0         0 $self->{_y_pin} = 6;
129 0         0 $self->{_nocomplement} = 1;
130 0 0       0 if($self->{_xspacing} > 16) { $self->{_yspacing} = 16; }
  0         0  
131             } elsif($args{machine} eq 'IAS') {
132             } else {
133 0         0 $self->{_format} = 1;
134 0         0 $self->{_print_dir} = 0;
135 0         0 $self->{_x_repeat} = 1;
136 0         0 $self->{_x_repeat} = 1;
137 0         0 $self->{_nocomplement} = 0;
138             }
139 1         3 &initialize($self);
140              
141 1         5 return $self;
142             }
143              
144             package SlideMap;
145             sub initialize {
146              
147 17     17 0 119 my $self = shift;
148 17   100     90 my $flag = shift || 0;
149              
150 17 50 33     88 if($self->{_xspacing} < 1 || $self->{_xspacing} eq '') {
151 0         0 die "x_spacing value not set\n"; }
152 17 50 33     73 if($self->{_yspacing} < 1 || $self->{_yspacing} eq '') {
153 0         0 die "y_spacing value not set\n"; }
154 17 50 33     69 if($self->{_x_repeat} < 1 || $self->{_x_repeat} > 4) {
155 0         0 die "x_repeat must be an integer between 1 and 4.\n"; }
156 17 50 33     65 if($self->{_y_repeat} < 1 || $self->{_y_repeat} > 4) {
157 0         0 die "x_repeat must be an integer between 1 and 4.\n"; }
158              
159 17 100       36 if($self->{_format} == 2) {
160 13         30 $self->{_max_plate_row} = 16;
161 13         25 $self->{_max_plate_col} = 24;
162 13         32 $self->{_max_xpass} = 16 / $self->{_x_pin};
163 13         22 $self->{_max_ypass} = 24 / $self->{_y_pin};
164             } else {
165 4         6 $self->{_max_plate_row} = 8;
166 4         6 $self->{_max_plate_col} = 12;
167 4         9 $self->{_max_xpass} = 8 / $self->{_x_pin};
168 4         8 $self->{_max_ypass} = 12 / $self->{_y_pin};
169             }
170 17 50       49 if($self->{_x_pin} > $self->{_max_plate_row}) {
171 0         0 die "x_pin must be an even integer <= plate row dimension\n"; }
172 17 50       42 if($self->{_y_pin} > $self->{_max_plate_col}) {
173 0         0 die "y_pin must be an even integer <= plate column dimension\n"; }
174             $self->{_num_wells} = $self->{_max_plate_row}
175 17         35 * $self->{_max_plate_col};
176             $self->{_pass_plate} = $self->{_max_xpass}
177 17         28 * $self->{_max_ypass};
178             $self->{_max_row} = $self->{_yspacing} * $self->{_y_pin}
179 17         36 * $self->{_y_repeat};
180             $self->{_max_col} = $self->{_xspacing} * $self->{_x_pin}
181 17         32 * $self->{_x_repeat};
182 17         24 $self->{_num_spots} = $self->{_max_row} * $self->{_max_col};
183             $self->{_num_plates} = int(($self->{_num_spots} - 1)/
184             ($self->{_x_repeat} * $self->{_y_repeat}
185 17         53 * $self->{_num_wells})) + 1;
186             # $self->{_max_pass} = $self->{_num_plates} * $self->{_pass_plate};
187 17 100       35 if(! $flag) {
188 16         67 @{ $self->{_plates} } = ( 1 .. $self->{_num_plates} );
  16         90  
189             }
190 17         44 $self->{_paramA} = $self->{_max_plate_row}/(2 * $self->{_x_pin});
191 17         44 $self->{_paramB} = 2 * $self->{_x_pin};
192              
193 17         46 my $code1 = &make_convert_well($self);
194 17 50       7573 $self->{_convert_well} = eval "sub { $code1 }" or die $!;
195 17         63 my $code2 = &make_convert_spot($self);
196 17 50       3587 $self->{_convert_spot} = eval "sub { $code2 }" or die $!;
197            
198             }
199              
200             package SlideMap;
201             sub fill_map {
202 6     6 0 38723 my $self = shift;
203 6         25 for my $i (1 .. $self->{_max_row}) {
204 1518         2907 for my $j (1 .. $self->{_max_col}) {
205 141408         206121 my $spot = (($i - 1) * $self->{_max_col}) + $j;
206 141408         227919 my ($plate, $well) = &convert_spot($self, $i, $j);
207 141408         229078 my $current_plate = $self->{_plates}->[$plate - 1];
208 141408         450021 $self->{_map}->[$spot] = [ $i, $j, $current_plate,
209             $well ];
210             }
211             }
212 6         50 return $self->{_map};
213             }
214              
215             package SlideMap;
216             sub diagnostics {
217 0     0 0 0 my($self) = shift;
218 0         0 print "machine: $self->{_machine}\n";
219 0         0 print "x_pin: $self->{_x_pin}\ty_pin: $self->{_y_pin}\txspacing:"
220             . " $self->{_xspacing}\t";
221 0         0 print "yspacing: $self->{_yspacing}\n";
222 0         0 print "x_repeat: $self->{_x_repeat}\ty_repeat: $self->{_y_repeat}\n";
223 0 0       0 if($self->{_machine} eq 'Lucidia') {
224 0         0 print "paramA: $self->{_paramA}\tparamB: $self->{_paramB}\n";
225             }
226 0         0 print "max_xpass: $self->{_max_xpass}\tmax_ypass: "
227             . "$self->{_max_ypass}\t";
228 0         0 print "pass_plate: $self->{_pass_plate}\n";
229 0         0 print "max_row: $self->{_max_row}\tmax_col: $self->{_max_col}"
230             . "\tnum_wells: ";
231 0         0 print "$self->{_num_wells}: \tnum_spots: $self->{_num_spots}\n";
232 0         0 print "format: $self->{_format}\tprint_dir: $self->{_print_dir}\n";
233 0         0 print "nocomplement: $self->{_nocomplement}\trepeat mode: "
234             . "$self->{_repeat}\n";
235 0         0 print "num_plates: $self->{_num_plates}\n";
236 0         0 print "plate_order: @{ $self->{_plates} }\n";
  0         0  
237             }
238              
239             package SlideMap;
240             sub print_spots {
241 0     0 0 0 my $self = shift;
242 0   0     0 my $w = shift || 0;
243 0         0 for my $y (1 .. $self->{_max_row}) {
244 0         0 for my $x (1 .. $self->{_max_col}) {
245 0         0 my $array_row = $y;
246 0         0 my $array_col = $x;
247             my $meta_row = int(($array_row - 1)
248 0         0 / $self->{_yspacing}) + 1;
249             my $meta_col = int(($array_col - 1)
250 0         0 / $self->{_xspacing}) + 1;
251 0         0 my ($plate_num, $well, $plate_row, $plate_col)
252             = &convert_spot($self,$array_row,$array_col);
253             my $block = ((($meta_row) - 1) * $self->{_x_pin})
254 0         0 + $meta_col;
255 0 0       0 if(length($plate_num) == 1) {
    0          
256 0         0 $plate_num = "00" . $plate_num;
257             } elsif(length($plate_num) == 2) {
258 0         0 $plate_num = "0" . $plate_num;
259             }
260 0 0       0 if($w == 1) {
261 0 0       0 if(length($well) == 1) {
    0          
262 0         0 $well = "00" . $well;
263             } elsif(length($well) == 2) {
264 0         0 $well = "0" . $well;
265             }
266 0         0 print "$array_row\t$array_col\t$plate_num\t"
267             . "$well\n";
268             } else {
269 0         0 my $rowstr = substr("ABCDEFGHIJKLMNOP",
270             $plate_row - 1, 1);
271 0 0       0 if(length($plate_col) == 1) {
272 0         0 $plate_col = "0" . $plate_col;
273             }
274 0         0 print "$array_row\t$array_col\t$plate_num\t"
275             . "$rowstr$plate_col\n";
276             }
277             }
278             # }
279             }
280             }
281              
282             package SlideMap;
283             sub print_wells {
284 0     0 0 0 my $self = shift;
285 0   0     0 my $w = shift || 0;
286 0         0 foreach my $plate_num (@{ $self->{_plates} }) {
  0         0  
287 0         0 foreach my $well (1 .. $self->{_num_wells}) {
288 0         0 my $row = int(($well - 1) / $self->{_max_plate_col}) + 1;
289 0         0 my $col = int(($well - 1) % $self->{_max_plate_col}) + 1;
290 0         0 my @data_refs = &convert_well($self,$plate_num,$well);
291 0         0 foreach my $ref (@data_refs) {
292 0         0 my ($array_row, $array_col, $meta_row, $meta_col,
293             $sub_row, $sub_col) = @$ref;
294 0         0 my $plate_str;
295 0 0       0 if(length($plate_num) == 1) {
    0          
296 0         0 $plate_str = "00" . $plate_num;
297             } elsif(length($plate_num) == 2) {
298 0         0 $plate_str = "0" . $plate_num;
299             } else {
300 0         0 $plate_str = $plate_num;
301             }
302 0 0       0 if($w == 1) {
303 0 0       0 if(length($well) == 1) {
    0          
304 0         0 $well = "00" . $well;
305             } elsif(length($well) == 2) {
306 0         0 $well = "0" . $well;
307             }
308 0         0 print "$plate_str\t$well\t$array_row\t$array_col\n";
309             } else {
310 0         0 my $rowstr = substr("ABCDEFGHIJKLMNOP", $row - 1, 1);
311 0         0 my $plate_col;
312 0 0       0 if(length($col) == 1) {
313 0         0 $plate_col = "0" . $col;
314             } else {
315 0         0 $plate_col = $col;
316             }
317 0         0 print "$plate_str\t$rowstr$plate_col\t$array_row\t"
318             . "$array_col\n";
319             }
320             }
321             }
322             }
323             }
324              
325             package SlideMap;
326             sub convert_well {
327 0     0 0 0 my $self = $_[0];
328 0         0 my @data = $self->{_convert_well}->(@_);
329 0         0 return @data;
330             }
331              
332             package SlideMap;
333             sub convert_spot {
334 141413     141413 0 286967 my $self = $_[0];
335 141413         2288560 my @data = $self->{_convert_spot}->(@_);
336 141413         299101 return @data;
337             }
338              
339             sub get_meta {
340 0     0 0 0 my($self, $_array_row, $_array_col) = @_;
341              
342             ## get current 'meta' pin coordinates
343 0         0 my $_meta_row = int(($_array_row - 1) / $self->{_yspacing}) + 1;
344 0         0 my $_meta_col = int(($_array_col - 1) / $self->{_xspacing}) + 1;
345              
346             ## now find sub-grid coordinates
347 0         0 my $_sub_row = $_array_row - (($_meta_row - 1) * $self->{_yspacing});
348 0         0 my $_sub_col = $_array_col - (($_meta_col - 1) * $self->{_xspacing});
349              
350 0         0 return ($_meta_row,$_meta_col,$_sub_row,$_sub_col);
351             }
352              
353             package SlideMap;
354             sub setFormat {
355 1     1 0 5 my($self,$informat) = @_;
356 1 50 33     5 if($informat == 1 || $informat == 2) {
357 1         3 $self->{_format} = $informat;
358 1         6 &initialize($self);
359             } else {
360 0         0 print "Format error: 1 = 96-well, 2 = 384-well\n";
361             }
362 1         6 return $self->{_format};
363             }
364              
365             sub setPrintDirection {
366 1     1 0 6 my($self,$dir) = @_;
367 1 50 33     33 if($dir == 0 || $dir == 1) {
368 1         4 $self->{_print_dir} = $dir;
369             } else {
370 0         0 print "Print Direction error: '0' => top->bottom, "
371             . "'1' => left->right\n";
372             }
373 1         2 return $self->{_print_dir};
374             }
375             sub setNoComplement {
376 1     1 0 7 my ($self,$nocomp) = @_;
377 1 50 33     5 if($nocomp == 0 || $nocomp == 1) {
378 1         4 $self->{_nocomplement} = $nocomp;
379             } else {
380 0         0 print "Complement error: '0' => complemented, "
381             . "'1' => NOT complemented\n";
382             }
383 1         2 return $self->{_nocomplement};
384             }
385             sub setRepeatMode {
386 0     0 0 0 my ($self,$mode) = @_;
387 0 0       0 if($mode == 1) {
    0          
388 0         0 $self->{_repeat} = $mode;
389 0 0 0     0 if($self->{_machine} eq 'MD' || $self->{_machine} eq 'MD3') {
390 0         0 $self->{_x_repeat} = 1;
391 0         0 $self->{_y_repeat} = 1;
392 0         0 $self->{_print_dir} = 0;
393 0 0       0 if($self->{_machine} eq 'MD3') {
394 0         0 $self->{_xspacing} = 32;
395 0         0 $self->{_yspacing} = 12;
396             } else {
397 0         0 $self->{_xspacing} = 16;
398 0         0 $self->{_yspacing} = 16;
399             }
400             }
401             } elsif($mode == 0) {
402 0         0 $self->{_repeat} = $mode;
403 0 0 0     0 if($self->{_machine} eq 'MD' || $self->{_machine} eq 'MD3') {
404 0         0 $self->{_x_repeat} = 2;
405 0         0 $self->{_y_repeat} = 1;
406 0 0       0 if($self->{_machine} eq 'MD3') {
407 0         0 $self->{_print_dir} = 1;
408             } else {
409 0         0 $self->{_print_dir} = 0;
410             }
411             }
412             } else {
413 0         0 print "Repeat error: '0' => normal mode, '1' => repeat"
414             . "mode\n";
415             }
416 0         0 return $self->{_repeat};
417             }
418             sub setRepeats {
419 2     2 0 13 my ($self,$xrep,$yrep) = @_;
420 2 50 33     13 if($xrep > 0 && $xrep < 5) {
421 2         8 $self->{_x_repeat} = $xrep;
422             } else {
423 0         0 print "Repeat error: '1' => NO repeat, '2','3','4' "
424             . "repeats in x dimension\n";
425             }
426 2 50 33     9 if($yrep > 0 && $yrep < 5) {
427 2         5 $self->{_y_repeat} = $yrep;
428             } else {
429 0         0 print "Repeat error: '1' => NO repeat, '2','3','4' "
430             . "repeats in y dimension\n";
431             }
432 2         5 return $self->{_x_repeat},$self->{_y_repeat};
433             }
434             sub setPlateOrder {
435 1     1 0 6 my $self = shift;
436 1         3 my $order_string = shift;
437 1         42 my @tmp = split(/\W+/,$order_string);
438 1 50       5 if($order_string eq '') {
439 0         0 @{ $self->{_plates} } = (1 .. $self->{_num_plates});
  0         0  
440             } else {
441 1         3 @{ $self->{_plates} } = @tmp;
  1         15  
442             }
443             # re-initialize with flag = 1 so plate_order is not re-set
444 1         5 &initialize($self,1);
445 1         9 return $self->{_plates};
446             }
447             sub setPrintHead {
448 2     2 0 17 my($self,$x,$y) = @_;
449 2 50 33     13 if($x > 0 && $y > 0) {
450 2         5 $self->{_x_pin} = int($x);
451 2         4 $self->{_y_pin} = int($y);
452 2         4 &initialize($self);
453             } else {
454 0         0 print "Print head dimensions must be non-zero integers.\n";
455             }
456 2         9 return $self->{_x_pin},$self->{_y_pin};
457             }
458              
459             sub setBlockDimensions {
460 4     4 0 28 my($self,$xs,$ys) = @_;
461 4 50 33     27 if($xs > 0 && $ys > 0) {
462 4         15 $self->{_xspacing} = int($xs);
463 4         9 $self->{_yspacing} = int($ys);
464 4         10 &initialize($self);
465             } else {
466 0         0 print "Block dimensions must be non-zero integers.\n";
467             }
468 4         14 return;
469             }
470              
471             sub setMachine {
472 4     4 0 221 my($self,$machine) = @_;
473              
474 4         14 $self->{_machine} = $machine;
475 4 100       40 if($machine eq 'MD3') {
    100          
    100          
    50          
    50          
476 1         4 $self->{_format} = 2;
477 1         3 $self->{_print_dir} = 1;
478 1         3 $self->{_x_repeat} = 2;
479 1         2 $self->{_y_repeat} = 1;
480 1         2 $self->{_xspacing} = 32;
481 1         3 $self->{_x_pin} = 1;
482 1         2 $self->{_y_pin} = 12;
483 1         3 $self->{_nocomplement} = 1;
484             } elsif($machine eq 'Lucidia') {
485 1         4 $self->{_format} = 2;
486 1         2 $self->{_print_dir} = 1;
487 1         4 $self->{_x_repeat} = 1;
488 1         2 $self->{_y_repeat} = 1;
489 1         3 $self->{_nocomplement} = 0;
490 1         2 $self->{_x_pin} = 2;
491 1         3 $self->{_y_pin} = 12;
492             } elsif($machine eq 'Stanford') {
493 1         6 $self->{_format} = 2;
494 1         3 $self->{_print_dir} = 0;
495 1         2 $self->{_x_pin} = 4;
496 1         2 $self->{_y_pin} = 4;
497 1         4 $self->{_x_repeat} = 1;
498 1         2 $self->{_y_repeat} = 1;
499 1         3 $self->{_nocomplement} = 0;
500             } elsif($machine eq 'MD') {
501 0         0 $self->{_format} = 1;
502 0         0 $self->{_print_dir} = 1;
503 0         0 $self->{_x_repeat} = 2;
504 0         0 $self->{_y_repeat} = 1;
505 0         0 $self->{_yspacing} = 16;
506 0         0 $self->{_x_pin} = 1;
507 0         0 $self->{_y_pin} = 6;
508 0         0 $self->{_nocomplement} = 1;
509             } elsif($machine eq 'IAS') {
510 1         3 $self->{_format} = 1;
511 1         2 $self->{_print_dir} = 0;
512 1         2 $self->{_x_repeat} = 1;
513 1         2 $self->{_y_repeat} = 1;
514 1         2 $self->{_nocomplement} = 0;
515             } else {
516 0         0 $self->{_format} = 1;
517 0         0 $self->{_print_dir} = 0;
518 0         0 $self->{_x_repeat} = 1;
519 0         0 $self->{_y_repeat} = 1;
520 0         0 $self->{_nocomplement} = 0;
521             }
522 4         15 $self->initialize;
523             }
524              
525 1     1 0 6 sub getFormat { return $_[0]->{_format}; }
526 1     1 0 7 sub getPrintDirection { return $_[0]->{_print_dir}; }
527 1     1 0 6 sub getNoComplement { return $_[0]->{_nocomplement}; }
528 2     2 0 14 sub getRepeats { return $_[0]->{_x_repeat}, $_[0]->{_y_repeat}; }
529 0     0 0 0 sub getRepeatMode { return $_[0]->{_repeat}; }
530 1     1 0 9 sub getPrintHead { return $_[0]->{_x_pin}, $_[0]->{_y_pin}; }
531             sub getBlockDimensions { return $_[0]->{_xspacing},
532 3     3 0 29 $_[0]->{_yspacing}; }
533 3     3 0 29 sub getMachine { return $_[0]->{_machine}; }
534 1     1 0 8 sub getPlateOrder { return $_[0]->{_plates}; }
535 6     6 0 55 sub getMap { return $_[0]->{_map}; }
536 0     0 0 0 sub getArrayDimensions { return $_[0]->{_max_row}, $_[0]->{_max_col}; }
537 0     0 0 0 sub getPitch { return $_[0]->{_x_pitch}, $_[0]->{_y_pitch}; }
538 0     0 0 0 sub getNumSpots { return $_[0]->{_num_spots}; }
539 0     0 0 0 sub showConvertWell { print "\nconvert_well:\n", &make_convert_well($_[0]); }
540 0     0 0 0 sub showConvertSpot { print "\nconvert_spot:\n", &make_convert_spot($_[0]); }
541              
542             sub make_convert_spot {
543              
544 17     17 0 31 my $self = shift;
545 17         32 my $code = '
546             my($self, $_array_row, $_array_col) = @_;
547             ';
548              
549             ## A. get current 'meta' pin coordinates
550              
551 17         36 $code .= '
552             my $_meta_row = int(($_array_row - 1) / $self->{_yspacing}) + 1;
553             my $_meta_col = int(($_array_col - 1) / $self->{_xspacing}) + 1;
554             ';
555              
556             ## B. get current pin coordinates
557              
558 17         26 $code .= '
559             my $_curr_ypin = int(($_meta_row - 1) / $self->{_y_repeat}) + 1;
560             my $_curr_xpin = int(($_meta_col - 1) / $self->{_x_repeat}) + 1;
561             ';
562              
563             ## C. now find sub-grid coordinates
564              
565 17         24 $code .= '
566             my $_spot_row = $_array_row - (($_meta_row - 1) * $self->{_yspacing});
567             my $_spot_col = $_array_col - (($_meta_col - 1) * $self->{_xspacing});
568             ';
569              
570 17 100       44 if($self->{_machine} eq 'Stanford') {
571 4         8 $code .= '
572             $_spot_col = ($self->{_xspacing} + 1 - $_spot_col);
573             ';
574             }
575 17         37 $code .= '
576             my $_sub_row = $_spot_row;
577             my $_sub_col = $_spot_col;
578             ';
579              
580             ## D. calc. cummulative head-pass, i.e. number of times head prints on slide
581              
582 17 100       38 if($self->{_print_dir} == 1) {
583             ## MD3 style printing; left -> right
584 6         11 $code .= '
585             my $_cum_pass = (($_spot_row - 1) * $self->{_xspacing}) + $_spot_col;
586             ';
587             } else {
588             ## default; IAS style printing; top -> bottom
589 11         17 $code .= '
590             my $_cum_pass = (($_spot_col - 1) * $self->{_yspacing}) + $_spot_row;
591             ';
592             }
593             ## get plate number, equivalent to ordinal
594 17         24 $code .= '
595             my $_plate_num = int(($_cum_pass - 1) / $self->{_pass_plate}) + 1;
596             ';
597             ## calc. current pass number
598 17         33 $code .= '
599             my $_curr_pass = int(($_cum_pass - 1) % $self->{_pass_plate}) + 1;
600             ';
601             ## now get x and y pass coordinates
602            
603 17 100       33 if($self->{_machine} eq 'Stanford') {
604 4         8 $code .= '
605             my $_x_pass = int(($_curr_pass - 1) / $self->{_max_ypass}) + 1;
606             my $_y_pass = int(($_curr_pass - 1) % $self->{_max_ypass}) + 1;
607             ';
608             } else {
609 13         24 $code .= '
610             my $_y_pass = int(($_curr_pass - 1) / $self->{_max_xpass}) + 1;
611             my $_x_pass = int(($_curr_pass - 1) % $self->{_max_xpass}) + 1;
612             ';
613             }
614              
615             ## E. now get plate row and col coordinates
616              
617 17 50 66     73 if($self->{_machine} eq 'Lucidia' && $self->{_nocomplement} == 1) {
    100          
    100          
618 0         0 $code .= '
619             my $_plate_row = (($_x_pass - 1) % $self->{_paramA})
620             * $self->{_paramA} + int(($_x_pass - 1) / $self->{_paramB})
621             + 2 * ($_curr_xpin) - 1;
622             ';
623             } elsif($self->{_machine} eq 'Lucidia') {
624 3         11 $code .= '
625             my $_plate_row = (($_x_pass - 1) % $self->{_paramA})
626             * $self->{_paramA} + int(($_x_pass - 1) / $self->{_paramB})
627             + 2 * (1 - $_curr_xpin + $self->{_x_pin}) - 1;
628             ';
629             } elsif($self->{_nocomplement} == 1) {
630 3         4 $code .= '
631             my $_plate_row = (($_x_pass - 1) * $self->{_x_pin}) + $_curr_xpin;
632             ';
633             } else {
634 11         23 $code .= '
635             my $_plate_row = (($_x_pass - 1) * $self->{_x_pin})
636             + (1 - $_curr_xpin + $self->{_x_pin});
637             ';
638             }
639 17         25 $code .= '
640             my $_plate_col = (($_y_pass - 1) * $self->{_y_pin}) + $_curr_ypin;
641             ';
642              
643             ## F. convert row, col coordinates to well number
644 17         31 $code .= '
645             my $_well = (($_plate_row - 1) * $self->{_max_plate_col}) + $_plate_col;
646             return ($_plate_num, $_well, $_plate_row, $_plate_col);
647             ';
648              
649 17         89 return $code;
650             }
651              
652              
653             sub make_convert_well {
654            
655 17     17 0 29 my($self) = shift;
656            
657 17         31 my $code = '
658             my($self, $_plate_num, $_well) = @_;
659             ';
660              
661             ## convert well number to row, col
662              
663 17         62 $code .= '
664             my $_row = int(($_well - 1) / $self->{_max_plate_col}) + 1;
665             my $_col = int(($_well - 1) % $self->{_max_plate_col}) + 1;
666             ';
667            
668             ## get current pin coordinates
669              
670 17 100       52 if($self->{_machine} eq 'Lucidia') {
    100          
671 3         8 $code .= '
672             my $_curr_xpin = $self->{_x_pin} - (int(($_row - 1)/2) % $self->{_x_pin});
673             ';
674             } elsif($self->{_nocomplement} == 1) {
675 3         8 $code .= '
676             my $_curr_xpin = (($_row - 1) % $self->{_x_pin}) + 1;
677             ';
678             } else {
679 11         37 $code .= '
680             my $_curr_xpin = $self->{_x_pin} - (($_row - 1) % $self->{_x_pin});
681             ';
682             }
683 17         33 $code .= '
684             my $_curr_ypin = (($_col - 1) % $self->{_y_pin}) + 1;
685             ';
686              
687             ## get pass numbers
688              
689 17 100       38 if($self->{_machine} eq 'Lucidia') {
690 3         6 $code .= '
691             my $_xpass = ((($_row - 1) % 2) * $self->{_paramA})
692             + int(($_row - 1) / $self->{_paramB}) + 1;
693             ';
694             } else {
695 14         32 $code .= '
696             my $_xpass = int(($_row - 1) / $self->{_x_pin}) + 1;
697             ';
698             }
699 17         28 $code .= '
700             my $_ypass = int(($_col - 1) / $self->{_y_pin}) + 1;
701             ';
702              
703             ## get cummulative print-head pass on plate
704              
705 17 100       36 if($self->{_machine} eq 'Stanford') {
706 4         10 $code .= '
707             my $_cum_pass = (($_plate_num - 1) * $self->{_pass_plate})
708             + (($_xpass - 1) * $self->{_max_ypass}) + $_ypass;
709             ';
710             } else {
711 13         25 $code .= '
712             my $_cum_pass = (($_plate_num - 1) * $self->{_pass_plate})
713             + (($_ypass - 1) * $self->{_max_xpass}) + $_xpass;
714             ';
715             }
716              
717             ## calc. sub-grid coordinates
718              
719 17 100       33 if($self->{_print_dir} == 1) {
720 6         15 $code .= '
721             my $_spot_row = int(($_cum_pass - 1) / $self->{_xspacing}) + 1;
722             my $_spot_col = int(($_cum_pass - 1) % $self->{_xspacing}) + 1;
723             ';
724             } else {
725 11         20 $code .= '
726             my $_spot_row = int(($_cum_pass - 1) % $self->{_yspacing}) + 1;
727             my $_spot_col = int(($_cum_pass - 1) / $self->{_yspacing}) + 1;
728             ';
729             }
730 17 100       41 if($self->{_machine} eq 'Stanford') {
731 4         8 $code .= '
732             $_spot_col = ($self->{_xspacing} + 1 - $_spot_col);
733             ';
734             }
735 17         27 $code .= '
736             my $_sub_row = $_spot_row;
737             my $_sub_col = $_spot_col;
738             ';
739              
740             ## calc. array coordinates
741             ## now handle the repeats and return a list of references to the data
742              
743 17         66 $code .= '
744             my($_array_row,$_array_col,$_meta_row,$_meta_col);
745             my @data;
746             for my $j (1 .. $self->{_y_repeat}) {
747             $_meta_row = $j + ($_curr_ypin - 1) * $self->{_y_repeat};
748             $_array_row = $_spot_row + ($_meta_row - 1) * $self->{_yspacing};
749             for my $i (1 .. $self->{_x_repeat}) {
750             $_meta_col = $i + ($_curr_xpin - 1) * $self->{_x_repeat};
751             $_array_col = $_spot_col + ($_meta_col - 1) * $self->{_xspacing};
752             push @data, [ $_array_row, $_array_col, $_meta_row, $_meta_col,
753             $_sub_row, $_sub_col ];
754             }
755             }
756             return @data;
757             ';
758            
759 17         40 return $code;
760             }
761              
762             1;
763             __END__