Synchronise crossovers in rotation features.
True on success. False if the type of any crossover is CrossoverType.unknown (which generates a CrossoverResult.error in crossover_results, if specified, due to inability to process crossover). Also returns False if unable to synchronise all crossovers due to an infinite cycle between crossovers. In all cases (success or failure) as many crossovers as possible will be processed and results saved to rotation features (and rotation files, if any).
A crossover occurs when the motion of a (moving) plate crosses over from one (fixed) plate to move relative to another (fixed) plate at a particular geological time. Synchronising a crossover involves adjusting the finite rotations before (older) the crossover to match the finite rotation after (younger) the crossover, or vice versa depending on the type of crossover.
Younger means more recent (smaller time values) and older means less recent (larger time values).
A crossover is represented as a named-tuple ‘Crossover’ with the following named elements:
|type||int||One of the enumerated values of CrossoverType (see table below).|
|time||float||The crossover time.|
|moving_plate_id||int||The moving plate ID.|
|young_crossover_fixed_plate_id||int||The fixed plate ID after (younger than) the crossover.|
|old_crossover_fixed_plate_id||int||The fixed plate ID before (older than) the crossover.|
|young_crossover_rotation_sequence||list of GpmlFiniteRotation||The time sequence of enabled finite rotations after (younger than) the crossover.|
|old_crossover_rotation_sequence||list of GpmlFiniteRotation||The time sequence of enabled finite rotations before (older than) the crossover.|
find_crossovers() for more information on the young/old rotation sequences in named-tuple ‘Crossover’.
rotation_features should contain all features that directly or indirectly affect the crossovers to be synchronised (typically rotation_features is one or more rotation files), otherwise crossovers may not be correctly synchronised.
Synchronising crossovers results in modifications to rotation_features. The modified rotation features can then be used to create a new RotationModel with updated rotations. If any filenames are specified in rotation_features then the modified feature collection(s) (containing synchronised crossovers) that are associated with those files are written back out to those same files. FeatureCollectionFileFormatRegistry is used internally to read/write feature collections from/to those files.
crossover_filter can optionally be used to limit (or specify) the crossovers to synchronise. It can either be a predicate function (accepting a single crossover argument) or a sequence of crossovers. If crossover_filter is not specified then all crossovers (found using find_crossovers() on rotation_features) will be synchronised. If crossover_filter is a predicate function then only those crossovers (found using find_crossovers() on rotation_features) that pass the predicate test will be synchronised. If crossover_filter is a sequence of crossovers then only crossovers in that sequence will be synchronised (and you must ensure that both the young and old sequences in each crossover have at least one enabled time sample otherwise the crossover can’t really be a crossover).
crossover_type_function is ignored if crossover_filter is a sequence of crossovers (since the crossover types are already known).
crossover_threshold_degrees can optionally be used to synchronise (fix) only those crossovers whose difference in young and old crossover rotation latitudes, longitudes or angles exceeds this amount. This is useful since some PLATES rotation files are typically only accurate to 2 decimal places (or threshold of 0.01).
CrossoverType supports the following enumeration values:
|CrossoverType.unknown||The crossover is of unknown type (it will not be synchronised).|
|CrossoverType.ignore||The crossover will be ignored (it will not be synchronised).|
|CrossoverType.synch_old_crossover_and_stages||All finite rotations in the old crossover sequence will be synchronised (such that old stage rotations are preserved). All finite rotations in the young crossover sequence are preserved.|
|CrossoverType.synch_old_crossover_only||Only the crossover finite rotation in the old crossover sequence will be synchronised (such that the older finite rotations are preserved). All finite rotations in the young crossover sequence are preserved.|
|CrossoverType.synch_young_crossover_and_stages||All finite rotations in the young crossover sequence will be synchronised (such that young stage rotations are preserved). All finite rotations in the old crossover sequence are preserved. Note: This can result in non-zero finite rotations at present day if the younger sequence includes present day.|
|CrossoverType.synch_young_crossover_only||Only the crossover finite rotation in the young crossover sequence will be synchronised (such that the younger finite rotations are preserved). All finite rotations in the old crossover sequence are preserved.|
crossover_type_function supports the following arguments:
|Arbitrary callable (function)||
A callable accepting the following arguments:
...and returning a CrossoverType enumerated value.
A callable (with same arguments as arbitrary callable) that uses the comment/description field of the young crossover pole to determine the crossover type according to the presence of the following strings/tags:
...and if none of those tags are present then the crossover type is CrossoverType.unknown.
This is the default for crossover_type_function.
|CrossoverTypeFunction.type_from_xo_tags_in_comment_default_xo_ys||Same as CrossoverTypeFunction.type_from_xo_tags_in_comment except defaults to CrossoverType.synch_old_crossover_and_stages if no tags are present in the comment/description field of the young crossover pole.|
|CrossoverTypeFunction.type_from_xo_tags_in_comment_default_xo_ig||Same as CrossoverTypeFunction.type_from_xo_tags_in_comment except defaults to CrossoverType.ignore if no tags are present in the comment/description field of the young crossover pole.|
|CrossoverType.unknown||All crossovers will be of type CrossoverType.unknown.|
|CrossoverType.ignore||All crossovers will be of type CrossoverType.ignore.|
|CrossoverType.synch_old_crossover_and_stages||All crossovers will be of type CrossoverType.synch_old_crossover_and_stages.|
|CrossoverType.synch_old_crossover_only||All crossovers will be of type CrossoverType.synch_old_crossover_only.|
|CrossoverType.synch_young_crossover_and_stages||All crossovers will be of type CrossoverType.synch_young_crossover_and_stages.|
|CrossoverType.synch_young_crossover_only||All crossovers will be of type CrossoverType.synch_young_crossover_only.|
crossover_results can optionally be used to obtain a list of the synchronisation results of all filtered crossovers (see crossover_filter). Each appended list element is a tuple of (Crossover, int) where the integer value is CrossoverResult.synchronised if the crossover was synchronised, or CrossoverResult.not_synchronised if the crossover did not require synchronising, or CrossoverResult.ignored if the crossover was ignored (due to a crossover type of CrossoverType.ignore), or CrossoverResult.error if the crossover was unable to be processed (due to a crossover type of CrossoverType.unknown). The appended list elements are sorted by crossover time.
Synchronise all crossovers found in a rotation file (and save modifications back to the same rotation file) where crossover types are determined by ‘@xo_’ tags in the young crossover description/comment:
Synchronise crossovers between present day and 20Ma found in a PLATES rotation file that has rotation latitudes, longitudes and angles rounded to 2 decimal places (and save modifications back to the same rotation file) assuming all crossovers are of type CrossoverType.synch_old_crossover_and_stages:
crossover_results =  pygplates.synchronise_crossovers( 'rotations.rot', lambda crossover: crossover.time <= 20, 0.01, # Equivalent to 2 decimal places pygplates.CrossoverType.synch_old_crossover_and_stages, crossover_results) print 'Fixed %d crossovers' % sum( 1 for result in crossover_results if result==pygplates.CrossoverResult.synchronised)