- Timestamp:
- Apr 29, 2011, 6:42:12 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/20110406/ippScripts/scripts/lap_science.pl
r31396 r31417 6 6 use Carp; 7 7 use IPC::Cmd 0.36 qw( can_run run); 8 use PS::IPP: Metadata::List qw( parse_md_list );8 use PS::IPP::Metadata::List qw( parse_md_list ); 9 9 use PS::IPP::Config 1.01 qw( :standard ); 10 10 use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt ); … … 25 25 my $laptool = can_run('laptool') or (warn "Can't find laptool" and $missing_tools = 1); 26 26 27 my ( $camera, $dbname, $logfile, $verbose, $debug); 28 my ( $proj_cell, $filter); 29 my ( $chip_mode, $diff_mode, $stack_mode, $qstack_mode, $magic_mode, $clean_mode); 30 31 32 27 my ( $help, $verbose, $debug); 28 my ( $camera, $dbname); 29 my ( $lap_id ); 30 my ( $chip_mode, $monitor_mode, $cleanup_mode); 31 32 GetOptions( 33 'help|h' => \$help, 34 'verbose' => \$verbose, 35 'debug' => \$debug, 36 37 'camera=s' => \$camera, 38 'dbname=s' => \$dbname, 39 40 'lap_id=s' => \$lap_id, 41 42 'chip_mode' => \$chip_mode, 43 'monitor_mode' => \$monitor_mode, 44 'cleanup_mode' => \$cleanup_mode, 45 ) or pod2usage ( 2 ); 46 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV; 47 pod2usage( 48 -msg => "Choose a mode: --chip_mode --monitor_mode --cleanup_mode", 49 -exitval => 3, 50 ) unless 51 defined $chip_mode or defined $monitor_mode or defined $cleanup_mode; 52 pod2usage( 53 -msg => "--lap_id is required", 54 -exitval => 3, 55 ) unless 56 defined $lap_id; 57 58 unless (defined $dbname) { 59 $dbname = 'gpc1'; 60 } 61 62 my $mdcParser = PS::IPP::Metadata::Config->new; 63 64 # Fetch all the information about this run 65 my %lapRunInfo = get_lapRun_info($lap_id); 66 67 # Run the appropriate mode 68 69 if (defined($chip_mode)) { 70 unless ($lapRunInfo{state} eq 'new') { 71 &my_die("Cannot run chip_mode if lapRun.state != new!",$lap_id); 72 } 73 my $status = chip_mode($lap_id); 74 exit $status; 75 } 76 if (defined($monitor_mode)) { 77 unless ($lapRunInfo{state} eq 'run') { 78 &my_die("Cannot run monitor_mode if lapRun != run!", $lap_id); 79 } 80 my $status = monitor_mode($lap_id); 81 exit $status; 82 } 83 if (defined($cleanup_mode)) { 84 unless (($lapRunInfo{state} eq 'done')|| 85 ($lapRunInfo{state} eq 'drop')) { 86 &my_die("Cannot run cleanup_mode if lapRun != done!", $lap_id); 87 } 88 my $status = cleanup_mode($lap_id); 89 exit $status; 90 } 33 91 34 92 # 35 93 # Chip 36 94 ################################################################################ 37 # This queues a chipRun for this exposure, and records the chip_id in the exposure structure and in the database 95 96 sub chip_mode { 97 my $lap_id = shift; 98 return(queue_chips($lap_id)); 99 } 100 101 # This creates the chiptool command to use for the specified parameters. 38 102 sub construct_chiptool_command { 39 103 my $lap_id = shift; … … 45 109 my $exp_id = shift; 46 110 47 my $cmd = "$chiptool "; 111 my $cmd = "$chiptool -pretend"; 112 $cmd .= " -pretend " if defined $debug; 48 113 $cmd .= " -dbname $dbname " if defined $dbname; 49 114 … … 53 118 return($cmd); 54 119 } 120 121 # retrieve the chip_id for the exposure inserted 55 122 sub get_chip_id_from_metadata { 56 123 my $exp_id = shift; … … 72 139 # There should be only one. 73 140 my $chip = ${ $chips }[0]; 74 my $chip_id = $chip->{chip_id}; 141 my $chip_id = 0; 142 if ($chip) { 143 $chip_id = $chip->{chip_id}; 144 } 75 145 76 146 return($chip_id); 77 147 } 148 149 sub get_lapRun_info { 150 my $lap_id = shift; 151 my $command = "$laptool -pendingrun -lap_id $lap_id"; 152 $command .= " -dbname $dbname " if defined $dbname; 153 my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 154 run(command => $command, verbose => $verbose); 155 unless ($success) { 156 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 157 &my_die("Unable to perform laptool: $error_code", $lap_id); 158 } 159 my $Runs = $mdcParser->parse_list(join "", @$stdout_buf) or 160 &my_die("Unable to parse metadata from laptool", $lap_id); 161 # There should be only one. 162 my $Run = ${ $Runs }[0]; 163 my %info = %{ $Run }; 164 return(%info); 165 } 166 167 168 # Queue a chipRun for this exposure with the appropriate parameters. 78 169 sub remake_this_exposure { 79 170 my $exposure = shift; … … 82 173 $utctime[5] += 1900; 83 174 $utctime[4] += 1; 175 176 my $label = $exposure->{label}; 177 84 178 my $date = sprintf("%4d%02d%02d",$utctime[5],$utctime[4],$utctime[3]); 85 179 my $workdir_date = sprintf("%4d/%02d/%02d",$utctime[5],$utctime[4],$utctime[3]); … … 92 186 $exposure->{exp_id}); 93 187 my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 94 run(command => $c ommand, verbose => $verbose);188 run(command => $chip_cmd, verbose => $verbose); 95 189 unless ($success) { 96 190 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); … … 98 192 } 99 193 100 $exposure->{chip_id} = get_chip_id_from_metadata($exposure->{exp_id},$exposure->{label},$data_group); #join "", @$stdout_buf);194 $exposure->{chip_id} = get_chip_id_from_metadata($exposure->{exp_id},$exposure->{label},$data_group); 101 195 $exposure->{data_state} = 'new'; 102 196 update_this_exposure($exposure); … … 106 200 # This is the "user level" subroutine. 107 201 sub queue_chips { 108 my $proj_cell = shift; 109 110 my $lap_id = get_lap_id($proj_cell); 202 my $lap_id = shift; 111 203 112 204 my $command = "$laptool -pendingexp -lap_id $lap_id"; … … 116 208 unless ($success) { 117 209 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 118 &my_die("Unable to perform laptool: $error_code", $ re_id, $proj_cell);119 } 120 121 if ( $@stdout_buf == 0) {210 &my_die("Unable to perform laptool: $error_code", $lap_id); 211 } 212 213 if (@$stdout_buf == 0) { 122 214 # Nothing to do. 123 215 return(0); 124 216 } 125 217 126 $exposures = $mdcParser->parse_list(join "", @$stdout_buf) or 127 &my_die("Unable to parse metadata from laptool", $re_id, $proj_cell); 128 129 # Preliminary scan of exposures to set up diff structures. 218 my $exposures = $mdcParser->parse_list(join "", @$stdout_buf) or 219 &my_die("Unable to parse metadata from laptool", $lap_id); 220 130 221 my $counter = 0; 131 222 my %matching = (); 132 223 my %indexing = (); 133 foreach my $exposure (@$exposures) { 134 my $lap_id = $exposure->{lap_id}; 224 # Determine which exposures need a chipRun queued. 225 foreach my $exposure (@$exposures) { 226 # $lap_id = $exposure->{lap_id}; # This should be already known. 135 227 my $tess_id = $exposure->{tess_id}; 136 228 my $exp_id = $exposure->{exp_id}; … … 145 237 my $comment = $exposure->{comment}; 146 238 147 if ( $chip_id) { # We already have a defined chip_id239 if (S64_IS_NOT_NULL($chip_id)) { # We already have a defined chip_id 148 240 if (($pairwise) && !($pair_id)) { 149 241 # This is an error. 150 &my_die("Exposure $exp_id for $lap_id is declared pairwise without a defined pair", $lap_id , $proj_cell);242 &my_die("Exposure $exp_id for $lap_id is declared pairwise without a defined pair", $lap_id); 151 243 } 244 $counter++; 245 next; 246 } 247 else { # We do not already have a chip_id. 248 # Make a chipRun, and update the exposure. 249 $exposure = remake_this_exposure($exposure); 250 251 # Save our information for diff pairing. 252 $matching{$object}{$comment} = $exp_id; 253 $indexing{$exp_id} = $counter; 152 254 $counter++; 153 next; 154 } 155 156 $exposure = remake_this_exposure($exposure); 157 # my $chip_cmd = construct_chiptool_command($lap_id,$proj_cell,$exp_id); 158 # my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 159 # run(command => $command, verbose => $verbose); 160 # unless ($success) { 161 # $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 162 # &my_die("Unable to perform chiptool: $error_code", $lap_id, $proj_cell); 163 # } 164 165 # $exposure->{chip_id} = get_chip_id_from_metadata(join "", @$stdout_buf); 166 167 # We will need to define a chipRun for this exposure. However, let's do diff matching before we do so. 168 169 $matching{$object}{$comment} = $exp_id; 170 $indexing{$exp_id} = $counter; 171 $counter++; 172 } 173 174 # Pair up exposures to diff. 175 foreach my $object (keys %matching) { 255 } 256 } 257 258 # Determine which exposures have a pair for diffing. 259 foreach my $object (keys %matching) { 176 260 my @exp_ids_to_diff = (); 177 261 foreach my $comment (keys %{ $matching{$object} }) { … … 184 268 } 185 269 186 while ($# { $exp_ids_to_diff }> -1) { # Save the pair information to the opposite exposure.270 while ($#exp_ids_to_diff > -1) { # Save the pair information to the opposite exposure. 187 271 my $exp_id_A = shift(@exp_ids_to_diff); 188 272 my $exp_id_B = shift(@exp_ids_to_diff); … … 198 282 } 199 283 } 200 201 # Queue chipRuns and update lapExp table. 202 foreach my $exposure (@$exposures) { 284 285 # Scan all exposures, and ensure that pairwise and private are set correctly 286 foreach my $exposure (@$exposures) { 203 287 if ($exposure->{pairwise} && !($exposure->{pair_id})) { 204 288 $exposure->{pairwise} = 0; # We marked it for pairwise diffs, but didn't match it. Probably an error. … … 208 292 } 209 293 210 update_this_exposure($exposure); 211 # my $lapE_cmd = construct_laptool_updateExp_command($lap_id, 212 # $exposure->{exp_id}, 213 # $exposure->{chip_id}, 214 # $exposure->{private}, 215 # $exposure->{pairwise}, 216 # $exposure->{pair_id}); 217 # my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 218 # run(command => $command, verbose => $verbose); 219 # unless ($success) { 220 # $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 221 # &my_die_with_fault("Unable to perform chiptool: $error_code", $lap_id, $proj_cell); 222 # } 294 $exposure = update_this_exposure($exposure); 223 295 } 224 296 } … … 245 317 246 318 ($defined_qstack,$have_qstack,$defined_fstack,$have_fstack) = (0,0,0,0); 247 if ( $@stdout_buf == 0) {319 if (@$stdout_buf == 0) { 248 320 # Nothing to do. Possibly an error, but for now, just accept it 249 321 return($defined_qstack,$have_qstack,$defined_fstack,$have_fstack); 250 322 } 251 323 252 $stacks = $mdcParser->parse_list(join "", @$stdout_buf) or324 my $stacks = $mdcParser->parse_list(join "", @$stdout_buf) or 253 325 &my_die("Unable to parse metadata from laptool", $lap_id, ""); 254 326 … … 263 335 } 264 336 if ($stack->{final_stack_id}) { 265 $defi end_fstack = 1;337 $defined_fstack = 1; 266 338 $total_fstacks++; 267 339 } … … 296 368 unless ($success) { 297 369 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 298 &my_die("Unable to perform laptool: $error_code", $ re_id, $proj_cell);299 } 300 301 if ( $@stdout_buf == 0) {370 &my_die("Unable to perform laptool: $error_code", $lap_id, $proj_cell); 371 } 372 373 if (@$stdout_buf == 0) { 302 374 # Nothing to do. However, this is likely an error. 303 375 return(0); 304 376 } 305 377 306 $exposures = $mdcParser->parse_list(join "", @$stdout_buf) or307 &my_die("Unable to parse metadata from laptool", $ re_id, $proj_cell);378 my $exposures = $mdcParser->parse_list(join "", @$stdout_buf) or 379 &my_die("Unable to parse metadata from laptool", $lap_id, $proj_cell); 308 380 309 381 # Need to prescan to see who matches whom. 310 %match_hash = ();382 my %match_hash = (); 311 383 my $index = 0; 312 384 foreach my $exposure (@$exposures) { … … 392 464 unless ($success) { 393 465 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 394 &my_die("Unable to perform laptool: $error_code", $ re_id, $proj_cell);466 &my_die("Unable to perform laptool: $error_code", $lap_id, $proj_cell); 395 467 } 396 468 } … … 421 493 unless ($success) { 422 494 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 423 &my_die("Unable to perform chiptool: $error_code", $ exposure->{lap_id}, $exposure->{proj_cell});495 &my_die("Unable to perform chiptool: $error_code", $lap_id); 424 496 } 425 497 … … 433 505 $command .= " -dbname $dbname " if defined $dbname; 434 506 435 my($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =436 run(command => $command, verbose => $verbose); 437 unless ($success) { 438 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 439 &my_die("Unable to perform chiptool: $error_code", $ exposure->{lap_id}, $exposure->{proj_cell});507 ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 508 run(command => $command, verbose => $verbose); 509 unless ($success) { 510 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 511 &my_die("Unable to perform chiptool: $error_code", $lap_id); 440 512 } 441 513 … … 466 538 unless ($success) { 467 539 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 468 &my_die("Unable to perform chiptool: $error_code", $ exposure->{lap_id}, $exposure->{proj_cell});540 &my_die("Unable to perform chiptool: $error_code", $lap_id); 469 541 } 470 542 … … 478 550 $command .= " -dbname $dbname " if defined $dbname; 479 551 480 my($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =481 run(command => $command, verbose => $verbose); 482 unless ($success) { 483 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 484 &my_die("Unable to perform chiptool: $error_code", $ exposure->{lap_id}, $exposure->{proj_cell});552 ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 553 run(command => $command, verbose => $verbose); 554 unless ($success) { 555 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 556 &my_die("Unable to perform chiptool: $error_code", $lap_id); 485 557 } 486 558 … … 490 562 491 563 # Need to prescan to see who matches whom. 492 %match_hash = ();564 my %match_hash = (); 493 565 my $index = 0; 494 566 foreach my $exposure (@$exposures) { … … 508 580 } 509 581 510 my $command = "$difftoool "; 511 my $command .= " -dbname $dbname " if defined $dbname; 512 my $command .= " -set_label $label -set_workdir $workdir -set_data_group $data_group "; 513 my $command .= " -set_dist_group $dist_group "; 582 my @utctime = gmtime(); 583 $utctime[5] += 1900; 584 $utctime[4] += 1; 585 586 my $label = $exposure->{label}; 587 my $dist_group = $exposure->{dist_group}; 588 my $date = sprintf("%4d%02d%02d",$utctime[5],$utctime[4],$utctime[3]); 589 my $workdir_date = sprintf("%4d/%02d/%02d",$utctime[5],$utctime[4],$utctime[3]); 590 my $workdir = "neb://\@HOST\@.0/${dbname}/${label}/${workdir_date}"; 591 my $data_group = "${label}.${date}"; 592 593 my $command = "$difftool "; 594 $command .= " -dbname $dbname " if defined $dbname; 595 $command .= " -set_label $label -set_workdir $workdir -set_data_group $data_group "; 596 $command .= " -set_dist_group $dist_group "; 514 597 515 598 if ($exposure->{pairwise}) { # warpwarp 516 $companion = ${ $exposures }[$match_hash{$exposure->{chip_id}}];599 my $companion = ${ $exposures }[$match_hash{$exposure->{chip_id}}]; 517 600 $command .= " -definewarpwarp "; 518 601 $command .= "-input_label $label -template_label $label -backwards "; … … 539 622 foreach my $exposure (@$exposures) { 540 623 $exposure->{active} = 0; 541 $exposure = update_this_exposure($exposure); 624 update_this_exposure($exposure); 625 } 626 } 627 628 629 # 630 # Cleanup 631 ################################################################################ 632 633 # sub cleanup_exposures { 634 # my $command = "$laptool -inactive "; 635 # $command .= " -dbname $dbname " if defined $dbname; 636 637 # my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 638 # run(command => $command, verbose => $verbose); 639 # unless ($success) { 640 # $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 641 # &my_die("Unable to perform laptool: $error_code", "none", "none"); 642 # } 643 # if (@$stdout_buf == 0) { 644 # # Nothing to do. 645 # return(0); 646 # } 647 648 # my $exposures = $mdcParser->parse_list(join "", @$stdout_buf) or 649 # &my_die("Unable to parse metadata from laptool", $lap_id); 650 651 # foreach my $exposure (@$exposures) { 652 # foreach my $clean_mode (@clean_modes) { 653 # $command = $clean_mode->{COMMAND}; 654 # $clean_id = $clean_mode->{CLEAN_ID}; 655 # $clean_state = $clean_mode->{CLEAN_STATE}; 656 # if (($exposure->{$clean_id} != 0)&& 657 # (($exposure->{$clean_state} eq 'full')|| 658 # ($exposure->{$clean_state} eq 'drop'))) { 659 660 # $command =~ s/\@DBNAME\@/$dbname/g; 661 # $command =~ s/\@CHIP_ID\@/$exposure->{chip_id}/; 662 # $command =~ s/\@CHIP_STATE\@/$exposure->{chip_state}/; 663 # $command =~ s/\@CHIP_LABEL\@/$exposure->{chip_label}/; 664 665 # $command =~ s/\@WARP_ID\@/$exposure->{chip_id}/; 666 # $command =~ s/\@WARP_STATE\@/$exposure->{chip_state}/; 667 # $command =~ s/\@WARP_LABEL\@/$exposure->{chip_label}/; 668 669 # $command =~ s/\@DIFF_ID\@/$exposure->{diff_id}/; 670 # $command =~ s/\@DIFF_STATE\@/$exposure->{diff_state}/; 671 # $command =~ s/\@DIFF_LABEL\@/$exposure->{diff_label}/; 672 673 # $command =~ s/\@MAGICDS_ID\@/$exposure->{magicDS_id}/; 674 # $command =~ s/\@MAGICDS_STATE\@/$exposure->{magicDS_state}/; 675 # $command =~ s/\@MAGICDS_LABEL\@/$exposure->{magicDS_label}/; 676 677 # ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 678 # run(command => $command, verbose => $verbose); 679 # unless ($success) { 680 # $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 681 # &my_die("Unable to perform laptool: $error_code", "none", "none"); 682 # } 683 # } 684 # } 685 # $exposure->{data_state} = 'cleaned'; 686 # update_this_exposure($exposure); 687 # } 688 # } 689 690 691 692 693 # 694 # Utilities 695 ################################################################################ 696 697 sub my_die { 698 my $msg = shift; # Warning message on die 699 my $lap_id = shift; # identifier 700 my $optional = shift; 701 my $exit_code = shift; 702 unless (defined $exit_code) { 703 $exit_code = $PS_EXIT_PROG_ERROR; 704 } 705 carp($msg); 706 exit $exit_code; 707 } 708 709 # Check to see if a 64bit integer is NULL or not. This is probably fragile, but I don't know how to get a S64 NULL out. 710 sub S64_IS_NOT_NULL { 711 if ($_[0] == 9223372036854775807) { 712 return(0); 713 } 714 else { 715 return(1); 542 716 } 543 717 } … … 587 761 &my_die("Unable to perform laptool: $error_code", $exposure->{lap_id}, $exposure->{proj_cell}); 588 762 } 589 590 } 591 592 # 593 # Cleanup 594 ################################################################################ 595 596 sub cleanup_exposures { 597 my $command = "$laptool -inactive "; 598 $command .= " -dbname $dbname " if defined $dbname; 599 600 my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 601 run(command => $command, verbose => $verbose); 602 unless ($success) { 603 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 604 &my_die("Unable to perform laptool: $error_code", "none", "none"); 605 } 606 if ($@stdout_buf == 0) { 607 # Nothing to do. 608 return(0); 609 } 610 611 foreach my $exposure (@$exposures) { 612 foreach my $clean_mode (@clean_modes) { 613 $command = $clean_mode->{COMMAND}; 614 $clean_id = $clean_mode->{CLEAN_ID}; 615 $clean_state = $clean_mode->{CLEAN_STATE}; 616 if (($exposure->{$clean_id} != 0)&& 617 (($exposure->{$clean_state} eq 'full')|| 618 ($exposure->{$clean_state} eq 'drop'))) { 619 620 $command =~ s/@DBNAME@/$dbname/g; 621 $command =~ s/@CHIP_ID@/$exposure->{chip_id}/; 622 $command =~ s/@CHIP_STATE@/$exposure->{chip_state}/; 623 $command =~ s/@CHIP_LABEL@/$exposure->{chip_label}/; 624 625 $command =~ s/@WARP_ID@/$exposure->{chip_id}/; 626 $command =~ s/@WARP_STATE@/$exposure->{chip_state}/; 627 $command =~ s/@WARP_LABEL@/$exposure->{chip_label}/; 628 629 $command =~ s/@DIFF_ID@/$exposure->{diff_id}/; 630 $command =~ s/@DIFF_STATE@/$exposure->{diff_state}/; 631 $command =~ s/@DIFF_LABEL@/$exposure->{diff_label}/; 632 633 $command =~ s/@MAGICDS_ID@/$exposure->{magicDS_id}/; 634 $command =~ s/@MAGICDS_STATE@/$exposure->{magicDS_state}/; 635 $command =~ s/@MAGICDS_LABEL@/$exposure->{magicDS_label}/; 636 637 ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 638 run(command => $command, verbose => $verbose); 639 unless ($success) { 640 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 641 &my_die("Unable to perform laptool: $error_code", "none", "none"); 642 } 643 } 644 } 645 $exposure->{data_state} = 'cleaned'; 646 update_this_exposure($exposure); 647 } 648 } 649 650 651 652 653 # 654 # Utilities 655 ################################################################################ 656 763 } 764
Note:
See TracChangeset
for help on using the changeset viewer.
