annotate base/charm/constructors.lisp @ 255:f1e6d10fdb11

pitched and unpitched Charm event constituent classes
author Jamie Forth <j.forth@gold.ac.uk>
date Thu, 24 Feb 2011 11:23:19 +0000
parents b5ffec94ae6d
children
rev   line source
j@253 1 (cl:in-package #:amuse-charm)
j@253 2
j@253 3 (defun make-charm-property-list (&rest properties)
j@253 4 (make-instance 'charm-property-list
j@253 5 :%data properties))
j@253 6
j@253 7 (defun make-charm-constituent-identifier (id)
j@253 8 (make-instance 'charm-constituent-identifier
j@253 9 :constituent-id id))
j@253 10
j@253 11 (defun make-standard-charm-constituent (particles parent
j@253 12 extrinsic-properties
j@253 13 intrinsic-properties &key
j@253 14 start duration
j@253 15 constituent-identifier owner
j@253 16 version creation-timestamp
j@253 17 deletion-timestamp)
j@253 18 "Properties should be charm-property-lists. FIXME: enforce this?
j@253 19 What about time? Should we be using implementation time data-types?
j@253 20 Particles by definition are identifiers - BUT this seemed to cause
j@253 21 unnecessary pain, so particales are now either events or
j@253 22 constituents. This could be made to call a backend specific
j@253 23 constructor specialised on the parent-identifier."
j@253 24 (make-instance 'standard-charm-constituent
j@253 25 :identifier constituent-identifier
j@253 26 :parent parent
j@253 27 :time start ; FIXME: naming conventions?
j@253 28 :interval duration
j@253 29 :extrinsic-properties extrinsic-properties
j@253 30 :intrinsic-properties intrinsic-properties
j@253 31 :%data particles
j@253 32 :owner owner
j@253 33 :version version
j@253 34 :creation-timestamp creation-timestamp
j@253 35 :deletion-timestamp deletion-timestamp))
j@253 36
j@253 37 (defun make-standard-charm-event-constituent (particles parent
j@253 38 extrinsic-properties
j@253 39 intrinsic-properties
j@253 40 &key start duration
j@253 41 constituent-identifier
j@253 42 owner version
j@253 43 creation-timestamp
j@253 44 deletion-timestamp)
j@255 45 (let ((constituent-class (cond
j@255 46 ((every #'amuse-utils:pitchedp particles)
j@255 47 'standard-charm-pitched-event-constituent)
j@255 48 ((every #'amuse-utils:unpitchedp particles)
j@255 49 'standard-charm-unpitched-event-constituent)
j@255 50 (t 'standard-charm-event-constituent))))
j@255 51 (make-instance constituent-class
j@255 52 :identifier constituent-identifier
j@255 53 :parent parent
j@255 54 :time start ; FIXME: naming conventions?
j@255 55 :interval duration
j@255 56 :extrinsic-properties extrinsic-properties
j@255 57 :intrinsic-properties intrinsic-properties
j@255 58 :%data particles
j@255 59 :owner owner
j@255 60 :version version
j@255 61 :creation-timestamp creation-timestamp
j@255 62 :deletion-timestamp deletion-timestamp)))
j@253 63
j@253 64 (defun composition->charm-constituent (composition
j@253 65 extrinsic-properties
j@253 66 intrinsic-properties)
j@253 67 "This is currently the bridge that takes us from AMuSE compositions
j@253 68 to Charm constituents."
j@253 69 (make-standard-charm-event-constituent (%list-slot-sequence-data
j@253 70 composition) composition
j@253 71 extrinsic-properties
j@253 72 intrinsic-properties
j@253 73 :start (timepoint
j@253 74 composition)
j@253 75 :duration (duration
j@253 76 composition)))
j@253 77
j@253 78 (defun make-onset-segment-constituent (composition)
j@253 79 "So this makes a constituent for each set of events with the same
j@253 80 onset, and adds all of those as particles to a parent constituent. To
j@253 81 two levels are created, maybe it's better to only return a list of
j@253 82 onset-constituents, and the user can group them together within
j@253 83 another constituent if necessary?"
j@253 84 (let ((grouped-events (group-by-onset composition))
j@253 85 (parent-constituent
j@253 86 (make-standard-charm-constituent nil composition
j@253 87 (make-charm-property-list
j@253 88 'sequence-class)
j@253 89 (make-charm-property-list
j@253 90 'sequence-class)
j@253 91 :start (timepoint
j@253 92 composition)
j@253 93 :duration (duration
j@253 94 composition))))
j@253 95 (loop for beat-events in grouped-events
j@253 96 collect (make-standard-charm-event-constituent
j@253 97 beat-events
j@253 98 parent-constituent
j@253 99 (make-charm-property-list 'segment)
j@253 100 (make-charm-property-list 'onset-segment))
j@253 101 into constituents
j@253 102 finally (progn
j@253 103 (setf (%list-slot-sequence-data parent-constituent)
j@253 104 constituents)
j@253 105 (return parent-constituent)))))
j@253 106
j@253 107 (defun group-by-onset (composition)
j@253 108 (loop for event in (reverse (%list-slot-sequence-data composition))
j@253 109 with grouped-events
j@253 110 do (if (and grouped-events
j@253 111 (time= (onset event) (onset (car (car grouped-events)))))
j@253 112 (push event (car grouped-events))
j@253 113 (push (list event) grouped-events))
j@253 114 finally (return grouped-events)))
j@253 115
j@253 116 (defun segment-at-bar (composition)
j@253 117 "Returns a list of bar-constituents."
j@255 118 (loop with current-bar = (current-bar (elt composition 0) composition)
j@255 119 and current-events
j@253 120 for event in (%list-slot-sequence-data composition)
j@253 121 if (time= current-bar (current-bar event composition))
j@253 122 do (push event current-events)
j@253 123 else
j@253 124 collect (make-standard-charm-event-constituent
j@253 125 (reverse current-events)
j@253 126 composition
j@253 127 (make-charm-property-list)
j@253 128 (make-charm-property-list 'segment 'bar))
j@253 129 into constituents
j@253 130 and do (setf current-bar (current-bar event composition))
j@253 131 and do (setf current-events nil)
j@253 132 finally (return constituents)))