From VisualWorks® NonCommercial, 7.2 of November 3, 2003 on April 20, 2005 at 6:45:18 am Segment CormasNS.Models false private Smalltalk.* private CormasNS.Kernel.* SegmentCategory Segment CormasNS.Models.Segment CormasNS.Kernel.CormasModel false none theCells theLitters theSeeds nameOfTheFile kill uneConnexion collecFinal dico SegmentCategory CormasNS.Models.Segment.Segment class accessing dico ^dico dico: anObject dico := anObject kill ^kill kill: aBoolean kill := aBoolean. nameOfTheFile ^nameOfTheFile nameOfTheFile: aFile nameOfTheFile := aFile. uneConnexion "Getter accessor with default value = nil " uneConnexion isNil ifTrue:[uneConnexion := nil]. ^uneConnexion uneConnexion: anObject uneConnexion := anObject CormasNS.Models.Segment.Segment instance-creation changeidGrid "Creation nouvel id" | collec temp | collec := Cormas sort: theCells byDecreasing: #numLine thenByIncreasing: #numCol. temp := 1. collec size timesRepeat: [collec first newid: temp. collec removeFirst. temp := temp + 1]. createAgregateLitter "Creation de l'aggregat litiere" self spaceModel setAggregatesFrom: Cell verifying: [:c | c newid < 101] into: Litter createGrid: file "Creation automatisee de la grille en fonction de la taille de la vegetation" | line nombreligne tmp item | line := ( file upTo: Character cr) readStream. line := ( file upTo: Character cr) readStream. tmp := OrderedCollection new. [line atEnd] whileFalse: [item := line upTo: Character tab. tmp add: item]. (tmp at: 6) asNumber = 0 ifTrue: [nombreligne := 200] ifFalse: [nombreligne := (tmp at: 6) asNumber]. file close. nombreligne := (nombreligne / 25) + 2. self spaceModel initializeRegularX: nombreligne Y: 100 shape: #squared nbNeighbours: #eight boundaries: #closed delimiter: true. initAgents: stream "Initialisation des graines et de leurs attributs a partir de la lecture du fichier input vegetation" | line seed tmp item depart dep | super initAgents. line := (stream upTo: Character cr) readStream. [stream atEnd] whileFalse: [line := (stream upTo: Character cr) readStream. tmp := OrderedCollection new. seed := Seed new. [line atEnd] whileFalse: [item := line upTo: Character tab. tmp add: item]. seed ds: (tmp at:1) asString. seed strat: (tmp at:2) asNumber. seed id: (tmp at:2) asNumber. seed cover: (tmp at: 3) asNumber. seed agreg: (tmp at: 4) asString. seed min: (tmp at: 5) asNumber. seed max: (tmp at: 6) asNumber. seed starter: self theCells asOrderedCollection. seed litter: self theLitters. self theSeeds add: seed. seed strat = 0 ifTrue: [depart := self theCells detect: [:c | c newid = 101]]. seed strat = 1 ifTrue: [depart := self theCells detect: [:c | c newid = 201]]. seed strat = 2 ifTrue: [depart := self theCells detect: [:c | c newid = 301]]. seed strat = 3 ifTrue: [depart := self theCells detect: [:c | c newid = 401]]. seed strat = 4 ifTrue: [seed max > 0 ifTrue: [dep := (((seed max / 25) + 1) * 100) + 1. depart := self theCells detect: [:c | c newid = dep]] ifFalse: [depart := self theCells detect: [:c | c newid = 701]]]. seed strat > 4 ifTrue: [dep := (((seed max / 25) + 1) * 100) + 1. depart := self theCells detect: [:c | c newid = dep]]. seed moveTo: depart.]. stream close. CormasNS.Models.Segment.Segment init InitBlock "Lancement du code phase d'initialisation: lecture des fichiers, creation grille, graines, litiere" | file name fileSp fileSpbis | Segment nameOfTheFile: (Dialog request: ('Name of the field data file ?') asString). name := Segment nameOfTheFile. fileSp := ((Cormas dataPath: self class name) construct: name,'.txt') readStream. fileSpbis:= ((Cormas dataPath: self class name) construct: name,'.txt') readStream. file := ((Cormas dataPath: self class name) construct: name,'Lit.txt') readStream. self createGrid: fileSp. self initCells: #init. self changeidGrid. self initAgents: fileSpbis. self createAgregateLitter. self theLitters do: [:c | c init: file]. self theCells do: [: c | c litter: (self theLitters asOrderedCollection) first]. self theCells do: [: c | c updateZ]. self initData. Seed stratId: 4. Seed totCov: 0. CormasNS.Models.Segment.Segment control run: t "Lance le code puis l'export des VF des familles de combustible" | ligneux herbe litiere num | self connect. self theSeeds do: [: s | s step]. self theCells do: [: c | c updateSpecies]. self theLitters do: [: l | l step]. num:= (Dialog request: (' run number :') asString). Segment dico: Dictionary new. self theSeeds do: [: s | s constituteDico]. self theCells do: [:c | c updateVFlitiere; updateVFherbe; updateVFligneux]. self disconnect. self updateData: t. ligneux := (Segment nameOfTheFile, num, '-Ligneous.txt') asString. herbe := (Segment nameOfTheFile, num, '-Grass.txt') asString. litiere := (Segment nameOfTheFile, num, '-Litter.txt') asString. self exportGridLigneux: #('numLigne' 'numCol' 'ds' 'leaves' 'twigs02' 'all02' 'all02dead' 'twigs26' 'twigs26dead' 'twigs625' 'twigs625dead' ) inFile: ((Cormas dataPath: self class name) construct: ligneux). self exportGridHerbe: #('numCol' 'comb' 'VF') inFile: ((Cormas dataPath: self class name) construct: herbe). self exportGridLitiere: #('numCol' 'ds' 'comb' 'VF') inFile: ((Cormas dataPath: self class name) construct: litiere). CormasNS.Models.Segment.Segment accessing theCells ^theCells theCells: x theCells := x theLitters ^theLitters theLitters: x theLitters := x theSeeds ^theSeeds theSeeds: x theSeeds := x CormasNS.Models.Segment.Segment export exportGridHerbe: attributes inFile: file | stream firstValue type firstPatch dicoAttConv patch a c depart | "pour exporter le fichier herbe" stream := file writeStream. dicoAttConv := Dictionary new. attributes do: [:att | firstPatch := self theCells detect: [:p | (p perform: att asSymbol) isNil not] ifNone: [nil]. firstPatch isNil ifTrue: [firstValue := nil] ifFalse: [firstValue := firstPatch perform: att asSymbol]. firstValue isSymbol ifTrue: [type := '(Symbol)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Number) ifTrue: [type := '(Number)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [firstValue isString ifTrue: [type := '(String)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Boolean) ifTrue: [type := '(Boolean)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [type := '(nil)'. dicoAttConv at: att asSymbol put: #printString]]]]. stream nextPutAll: att; nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]. " valeurs des attributs de chaque cellule de la ligne des herbes " depart := self theCells size - 199. depart to: self theCells size - 100 do: [:i | patch := self theCells at: i. attributes do: [:att | a := att asSymbol. c := dicoAttConv at: a. stream nextPutAll: ((patch perform: a) perform: c); nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]]. stream close exportGridLigneux: attributes inFile: file "pour exporter le fichier ligneux" | stream firstValue type firstPatch dicoAttConv patch a c | stream := file writeStream. dicoAttConv := Dictionary new. attributes do: [:att | firstPatch := self theCells detect: [:p | (p perform: att asSymbol) isNil not] ifNone: [nil]. firstPatch isNil ifTrue: [firstValue := nil] ifFalse: [firstValue := firstPatch perform: att asSymbol]. firstValue isSymbol ifTrue: [type := '(Symbol)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Number) ifTrue: [type := '(Number)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [firstValue isString ifTrue: [type := '(String)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Boolean) ifTrue: [type := '(Boolean)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [type := '(nil)'. dicoAttConv at: att asSymbol put: #printString]]]]. stream nextPutAll: att; nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]. " valeurs des attributs de chaque cellule de la grille sauf les 2 premieres lignes" 1 to: self theCells size - 201 do: [:i | patch := self theCells at: i. attributes do: [:att | a := att asSymbol. c := dicoAttConv at: a. stream nextPutAll: ((patch perform: a) perform: c); nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]]. patch := self theCells detect: [:k| k newid = 300]. attributes do: [:att | a := att asSymbol. c := dicoAttConv at: a. stream nextPutAll: ((patch perform: a) perform: c); nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: [''])]. stream close exportGridLitiere: attributes inFile: file "pour exporter le fichier litiere" | stream firstValue type firstPatch dicoAttConv patch a c depart | stream := file writeStream. dicoAttConv := Dictionary new. attributes do: [:att | firstPatch := self theCells detect: [:p | (p perform: att asSymbol) isNil not] ifNone: [nil]. firstPatch isNil ifTrue: [firstValue := nil] ifFalse: [firstValue := firstPatch perform: att asSymbol]. firstValue isSymbol ifTrue: [type := '(Symbol)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Number) ifTrue: [type := '(Number)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [firstValue isString ifTrue: [type := '(String)'. dicoAttConv at: att asSymbol put: #asString] ifFalse: [(firstValue isKindOf: Boolean) ifTrue: [type := '(Boolean)'. dicoAttConv at: att asSymbol put: #printString] ifFalse: [type := '(nil)'. dicoAttConv at: att asSymbol put: #printString]]]]. stream nextPutAll: att; nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]. " valeurs des attributs de chaque cellule de la ligne de litiere" depart := self theCells size - 99. depart to: self theCells size do: [:i | patch := self theCells at: i. attributes do: [:att | a := att asSymbol. c := dicoAttConv at: a. stream nextPutAll: ((patch perform: a) perform: c); nextPutAll: (att = attributes last ifFalse: [' '] ifTrue: ['\' withCRs])]]. stream close CormasNS.Models.Segment.Segment connectToDB connect "Definition des proprietes de la base a laquelle on se connecte" Segment uneConnexion: Database.ODBCConnection new. Segment uneConnexion username: 'root'; password:''; environment: 'bd_clump'. Segment uneConnexion connect. disconnect Segment uneConnexion disconnect. Seed CormasNS.Models.Segment CormasNS.Kernel.AgentLocation false none ds strat cover agreg min max firstOne starter litter covQI nbT totCov stratId SegmentCategory CurrentId CormasNS.Models.Segment.Seed false false As yet unclassified CormasNS.Models.Segment.Seed class id CurrentId ^CurrentId isNil ifTrue: [0] ifFalse: [CurrentId] CurrentId: x ^CurrentId := x CormasNS.Models.Segment.Seed class coverByStrate stratId ^stratId stratId: aValue stratId isNil ifTrue:[stratId := 4]. stratId := aValue totCov ^totCov totCov: aValue totCov isNil ifTrue:[totCov := 0]. totCov := aValue CormasNS.Models.Segment.Seed init init "intialisation graines et lien avec l'ensemble des cellules de la grille (starter)" super init. self starter: OrderedCollection new. initId self id: (self class CurrentId: self class CurrentId + 1) CormasNS.Models.Segment.Seed accessing agreg ^agreg agreg: anObject agreg := anObject cover ^cover cover: anObject cover := anObject covQI "taux de recourvement du chene vert" ^covQI covQI: anObject covQI := anObject ds "Espece dominante" ^ds ds: anObject ds := anObject firstOne "Emplacement initial de la graine, pour x=0 et z=hauteur de la vegetation" ^firstOne firstOne: anObject firstOne := anObject litter ^litter litter: anObject litter := anObject max ^max max: anObject max := anObject min ^min min: anObject min := anObject nbT "nombre de touffes" "Getter accessor with default value = 1 " nbT isNil ifTrue:[nbT := 1]. ^nbT nbT: anObject nbT := anObject starter "l'ensemble des cellules" ^starter starter: anObject starter := anObject strat ^strat strat: anObject strat := anObject CormasNS.Models.Segment.Seed pov povSeed "Pour la visualisation des graines" ^#seed. CormasNS.Models.Segment.Seed parameters calcCoefAgreg | coef | "calcul de l'espace entre touffes en fonction de l'agregation" self agreg = 'A' ifTrue: [coef := 0.2 * Cormas random]. self agreg = 'B' ifTrue: [coef := 0.2 + (0.4 * Cormas random)]. self agreg = 'C' ifTrue: [coef := 0.8 - (0.2 * Cormas random)]. self agreg = 'D' ifTrue: [coef := 1 - (0.2 * Cormas random)]. ^coef calcCoverByStrat "calcule le recouvrement total de la strate arbustive" "self strat = Seed stratId ifTrue: [Seed totCov: Seed totCov + self cover] ifFalse: [Seed stratId: self strat. Seed totCov: self cover]." Seed totCov: Seed totCov + self cover. calcCovQI | qi | qi := 0. self strat < 5 ifTrue: [qi := self starter select: [ :c | (c newid > 200 and: [c newid < 301]) and: [c shade = 1]]. qi isEmpty ifFalse: [qi := qi size] ifTrue: [qi := 0]]. ^qi calcDiameter: recCum and: i | diameter tmp | "calcul du diametre des touffes en fonction du nombre de touffes et du recouvrement" tmp := Cormas random. tmp < 0.5 ifTrue: [diameter := (self calcMeanDiam + (self calcMeanDiam * 0.3 * Cormas random)) asInteger] ifFalse: [diameter := (self calcMeanDiam - (self calcMeanDiam * 0.3 * Cormas random)) asInteger]. diameter = 0 ifTrue: [diameter := 1]. i = 1 ifTrue: [diameter :=self cover - recCum]. ^diameter calcEquid | equid | "calcul de l'equidistance entre touffes" equid := (100 - self covQI - self cover) / (self nbT+ 2). ^equid calcMeanDiam "Calcul du diametre moyen - HYPOTHESE Arbre diametre houppier = hauteur houppier" | meanDiam | " self strat > 4 ifTrue:[meanDiam := ((self max- self min) / 25) asInteger] ifFalse: [meanDiam := (self cover / self nbT) asInteger]. meanDiam = 0 ifTrue: [meanDiam :=1]. ^meanDiam" self strat > 4 ifTrue: [self ds = 'PP' ifTrue:[ self max=975 ifTrue: [meanDiam :=200/25]. self max=950 ifTrue: [meanDiam:=175/25]. self max=575 ifTrue: [meanDiam:=200/25]. self max=500 ifTrue: [meanDiam:=200/25]. self max=550 ifTrue: [meanDiam:=225/25]] ifFalse:[ meanDiam:= ((self max- self min) / 25) asInteger]] ifFalse: [meanDiam := (self cover / self nbT) asInteger]. meanDiam = 0 ifTrue: [meanDiam :=1]. ^meanDiam calcNbClump "Calcul du nbre de touffes - HYPOTHESE arbustes: nbr touffes = f (diagramme Folk)" | NbT tmp | tmp := Cormas random. self strat > 4 ifTrue: [self cover < self calcMeanDiam ifTrue: [NbT:= 1] ifFalse: [NbT:= self cover // self calcMeanDiam ]] ifFalse: [self agreg = 'A' ifTrue: [(tmp > 0.5 or: [self cover > 95]) ifTrue: [NbT:= 1] ifFalse: [NbT := 2]]. self agreg = 'B' ifTrue: [tmp < 0.3 ifTrue: [NbT:= 3]. (tmp between: 0.3 and: 0.6) ifTrue:[NbT:= 4]. tmp > 0.6 ifTrue: [NbT:= 5]]. self agreg = 'C' ifTrue: [tmp < 0.3 ifTrue: [NbT:= 6]. (tmp between: 0.3 and: 0.6) ifTrue:[NbT:= 7]. tmp > 0.6 ifTrue: [NbT:= 8]]. self agreg = 'D' ifTrue: [self cover > 11 ifTrue: [tmp <= 0.3 ifTrue: [NbT:= 9]. (tmp between: 0.3 and: 0.6) ifTrue:[NbT:= 10]. tmp > 0.6 ifTrue: [NbT:= 11]] ifFalse: [NbT := self cover]]]. self nbT: NbT CormasNS.Models.Segment.Seed control finishGrass "Si tout n'est pas fait du premier coup avec locateGrass - on met le reste des herbes au hasard la ou il reste de la place" | collec lit nextPos | collec := (self starter select: [:c | (c newid between: 101 and: 200) and: [c ds isNil]]) asOrderedCollection. nextPos := Cormas selectRandomlyFrom: collec. self moveTo: nextPos. self patch ds: self ds. self patch comb: self max. lit := self starter detect: [:c | c newid = (self patch newid - 100)]. ((lit domstrat isNil not) and: [lit ss isNil]) ifTrue: [lit ss: self ds]. lit domstrat isNil ifTrue: [lit domstrat: 1. lit ds: self ds]. finishShrubs: recCumCalc "Creation des autres arbustes lorsqu'une strate est composee de plusieurs especes (ne peut se faire que si locateShrubs a été lance une premiere fois)" | diameter dom end collec nextPos recCum | recCum := recCumCalc. dom := 2. self firstOne: ((self patch numLine - 1) * 100 + 1). end := self firstOne + 99. [self cover - recCum > 0] whileTrue: [collec := (self starter select: [:c | c id >= self firstOne and: [c id <= end and: [c bufferState = nil]]]) asSortedCollection: [:a :b | a id < b id]. nextPos := Cormas selectRandomlyFrom: collec. nextPos isNil not ifTrue: [self moveTo: nextPos. diameter := 1. self coordShapeDB: diameter. self indicDomStrat: diameter and: dom. self updateLitter: diameter. recCum := recCum + diameter] ifFalse: [Dialog warn: ' cover = ', recCum asValue printString, '%'. recCum := self cover]]. indicDomStrat: diameter and: dom "Indique la strate la plus haute qui domine la litiere" | grass lit initc | initc := self patch numCol. grass := self starter select: [:c | (c newid between: 101 and: 200) and: [ c numCol between: initc and: (initc + diameter - 1)]] . grass do: [:c | c domstrat = 0 ifTrue: [c domstrat: dom]]. lit := self starter select: [:c | (c newid between: 1 and: 100) and: [ c numCol between: initc and: (initc + diameter - 1 )]] . lit do: [:c | c domstrat = 0 ifTrue: [c domstrat: dom]]. indicQIShade: diameter "Indique toutes les cellules en dessous de chenes verts" | shade initc | initc := self patch numCol. shade := self starter select: [:c | (c newid between: 201 and: 1000) and: [ c numCol between: initc and: (initc + diameter)]] . shade do: [:c | c shade: 1]. initNextPos: end and: diameter1 and: diameter2 "Renvoie la cellule ou va se creer un nouvel arbre" | nextPos collec collec2 | collec := (self starter select: [:c | c id >= (self patch id + diameter1 + (self calcEquid * self calcCoefAgreg)) asInteger and: [c id <= end]]) asSortedCollection: [:a :b | a id < b id]. (collec isEmpty not and: [collec size >= diameter2]) ifTrue: [nextPos := collec first] ifFalse: [collec2 := (self starter select: [:c | c id >= (self patch id + diameter1 + 1) asInteger and: [c id <= end]]) asSortedCollection: [:a :b | a id < b id]. (collec2 isEmpty not and: [collec2 size >= diameter2]) ifTrue: [nextPos := collec2 first] ifFalse: [nextPos := nil]]. ^ nextPos. initNextShrub: end and: diameter1 and: diameter2 "Renvoie la cellule ou va se creer un nouvel arbuste" | nextPos collec collec2 | collec := (self starter select: [:c | c id >= (self patch id + diameter1 + (self calcEquid * self calcCoefAgreg)) asInteger and: [c id <= end and: [c shade = 0]]]) asSortedCollection: [:a :b | a id < b id]. (collec isEmpty not and: [collec size >= diameter2]) ifTrue: [nextPos := collec first] ifFalse: [collec2 := (self starter select: [:c | c id >= (self patch id + diameter1 + 1) asInteger and: [c id <= end and: [c shade = 0]]]) asSortedCollection: [:a :b | a id < b id]. (collec2 isEmpty not and: [collec2 size >= diameter2]) ifTrue: [nextPos := collec2 first] ifFalse: [nextPos := nil]]. ^nextPos locateGrass "Positionnement des plages enherbees" | dep1 recCum i long lit collec cpt nextPos firstCellPos | dep1 := (self calcEquid * Cormas random) asInteger. firstCellPos := self starter detect: [:c | c newid = (101 + dep1)]. self moveTo: firstCellPos. cpt := 0. self calcNbClump. i := self nbT. recCum := 0. [cpt < i] whileTrue: [long:= (self calcMeanDiam * (1+ (0.4 * Cormas random))) asInteger. long timesRepeat: [recCum < self cover ifTrue: [self patch ds: self ds. self patch comb: self max. recCum := recCum + 1. lit := self starter detect: [:c | c newid = (self patch newid - 100)]. ((lit domstrat isNil not) and: [lit ss isNil]) ifTrue: [lit ss: self ds]. lit domstrat isNil ifTrue: [lit domstrat: 1. lit ds: self ds]. collec := (self starter select: [:c | c newid > self patch newid and: [c newid < 201 and: [c domstrat ~= 3 and: [c ds isNil]]]]) asSortedCollection: [:a :b | a newid < b newid]. collec isEmpty ifFalse: [self moveTo: collec first] ifTrue: [recCum < self cover ifTrue: [(self cover - recCum) timesRepeat: [self finishGrass]]. recCum := self cover]]]. nextPos := (self patch newid + (self calcEquid * self calcCoefAgreg)) asInteger. collec := (self starter select: [:c | c newid > nextPos and: [c newid < 201 and: [c domstrat ~= 3 and: [c ds isNil]]]]) asSortedCollection: [:a :b | a newid < b newid]. collec isEmpty ifFalse: [self moveTo: collec first. cpt := cpt + 1] ifTrue: [recCum < self cover ifTrue: [(self cover - recCum) timesRepeat: [self finishGrass]]. recCum := self cover. cpt := i]]. recCum < self cover ifTrue: [(self cover - recCum) timesRepeat: [self finishGrass]] locateOtherShrubs "Creation des autres arbustes lorsqu'une strate est composee de plusieurs especes (ne peut se faire que si locateShrubs a été lance une premiere fois)" | recCum dom end collec nextPos i j jIndex nb x dic collecId keyExists diameter1 clefsOK uneClefOK collecPos diameter2 tcollec temp | recCum := 0. dom := 2. self firstOne: self patch id. end := self patch id + 99. self calcNbClump. i := self nbT. "Dictionnaire contenant les espaces vides - clefs = nbre de cases vides - valeur = collection des id de la cellule ou commence le vide" collec := (self starter select: [:c | c id >= self firstOne and: [c id <= end and: [c bufferState = nil]]]) asSortedCollection: [:a :b | a id < b id]. tcollec:= collec size. j := 1. jIndex:=(collec at: j) id. nb := 1. x := 1. keyExists:= true. dic := Dictionary new. collecId := OrderedCollection new. tcollec timesRepeat: [ ((collec at: j) id = (collec last) id) ifFalse: [x:= (collec at: (j+1)) id - (collec at: j) id. x = 1 ifTrue: [nb := nb +1] ifFalse: [ dic at: nb ifAbsent: [keyExists := false]. keyExists ifTrue: [ collecId := OrderedCollection new. collecId := dic at: nb. collecId add: jIndex. dic add: nb -> collecId]. keyExists ifFalse: [collecId := OrderedCollection new. collecId add: jIndex. dic add: nb -> collecId]. jIndex := (collec at: (j+1)) id. nb := 1. keyExists:= true]. j := j+1] ifTrue: [dic at:nb ifAbsent: [keyExists := false]. keyExists ifTrue: [ collecId := OrderedCollection new. collecId := dic at: nb. collecId add: jIndex. dic add: nb -> collecId]. keyExists ifFalse: [collecId := OrderedCollection new. collecId add: jIndex. dic add: nb -> collecId]]]. "Localisation arbustes" diameter1 := self calcDiameter: recCum and: i. clefsOK := dic keys select: [:k | k >= diameter1]. clefsOK size = 0 ifFalse: [clefsOK size = 1 ifTrue: [temp := clefsOK asOrderedCollection. uneClefOK := (temp at:1)] ifFalse: [uneClefOK := Cormas selectRandomlyFrom: clefsOK]. collecPos := dic at: uneClefOK. nextPos := Cormas selectRandomlyFrom: collecPos. collecPos remove: nextPos. collecPos isEmpty ifTrue: [dic removeKey: uneClefOK] ifFalse: [dic add: uneClefOK -> collecPos]. self moveTo: ((self starter select: [:c | c id = nextPos]) at:1). [i > 0] whileTrue: [self coordShapeDB: diameter1. self indicDomStrat: diameter1 and: dom. self updateLitter: diameter1. recCum := recCum + diameter1. i := i - 1. i >= 1 ifTrue: [diameter2 := self calcDiameter: recCum and: i. clefsOK := dic keys select: [:k | k >= diameter2]. clefsOK size = 0 ifFalse: [ clefsOK size = 1 ifTrue: [temp := clefsOK asOrderedCollection. uneClefOK := (temp at:1)] ifFalse: [uneClefOK := Cormas selectRandomlyFrom: clefsOK]. collecPos := dic at: uneClefOK. nextPos := Cormas selectRandomlyFrom: collecPos. collecPos remove: nextPos. collecPos isEmpty ifTrue: [dic removeKey: uneClefOK] ifFalse: [dic add: uneClefOK -> collecPos]. nextPos isNil not ifTrue: [self moveTo: ((self starter select: [:c | c id = nextPos]) at:1). diameter1 := diameter2]] ifTrue: [i:=0]]]]. clefsOK size = 0 ifTrue: [self finishShrubs: recCum]. locateQIShrubs "creation un a un des arbustes d'une espece donnée -et qui peuvent pousser sous le chene vert-" | recCum i nextPos dom dist end diameter1 diameter2 | self firstOne: self patch id. end := self patch id + 99. recCum := 0. dom := 2. self calcNbClump. i := self nbT. dist := (100 - (self nbT * self calcMeanDiam) - (self nbT * self calcEquid * self calcCoefAgreg)). nextPos := self starter at: (self patch id + ((dist * Cormas random) asInteger)). self moveTo: nextPos. diameter1 := self calcDiameter: recCum and: i. [i > 0] whileTrue: [self coordShapeDB: diameter1. self indicDomStrat: diameter1 and: dom. self updateLitter: diameter1. recCum := recCum + diameter1. i := i - 1. i >= 1 ifTrue: [diameter2 := self calcDiameter: recCum and: i. nextPos := self initNextPos: end and: diameter1 and: diameter2. nextPos isNil not ifTrue: [self moveTo: nextPos. diameter1 := diameter2] ifFalse: [i := 0. self finishShrubs: recCum]]]. locateShrubs "Creation un a un des arbustes d'une espece donnée -et qui ne pousse pas sous le chene vert-" | recCum i nextPos dom end dep1 collec dist diameter1 diameter2 | recCum := 0. dom := 2. self firstOne: self patch id. end := self patch id + 99. self calcNbClump. i := self nbT. dist := (100 - (self nbT * self calcMeanDiam) - (self nbT * self calcEquid * self calcCoefAgreg)). dep1 := self starter at: (self patch id + ((dist * Cormas random) asInteger)). collec := (self starter select: [:c | c id >= self patch id and: [c id <= end and: [c shade = 0]]]) asSortedCollection: [:a :b | a id < b id]. dep1 ~= 0 ifTrue: [nextPos := dep1] ifFalse: [nextPos := collec first]. self moveTo: nextPos. diameter1 := self calcDiameter: recCum and: i. [i > 0] whileTrue: [self coordShapeDB: diameter1. self indicDomStrat: diameter1 and: dom. self updateLitter: diameter1. recCum := recCum + diameter1. i := i - 1. i >= 1 ifTrue: [diameter2 := self calcDiameter: recCum and: i. nextPos := self initNextShrub: end and: diameter1 and: diameter2. nextPos isNil not ifTrue: [self moveTo: nextPos. diameter1 := diameter2] ifFalse: [i := 0. self finishShrubs: recCum]]]. locateTrees "Creation un a un des arbres d'une même strate" | recCum i nextPos dom dist end diameter1 diameter2 | recCum := 0. dom := 3. self firstOne: self patch id. end := self patch id + 99. self calcNbClump. i := self nbT. dist := 100 - (self nbT * self calcMeanDiam) - (self nbT * self calcEquid * self calcCoefAgreg). nextPos := self starter at: (self patch id + ((dist * Cormas random) asInteger)). self moveTo: nextPos. diameter1 := self calcDiameter: recCum and: i. [i > 0] whileTrue: [self coordShapeDB: diameter1. self indicDomStrat: diameter1 and: dom. self ds = 'QI' ifTrue: [self indicQIShade: diameter1]. self updateLitter: diameter1. recCum := recCum + diameter1. i := i - 1. i >= 1 ifTrue: [diameter2 := self calcDiameter: recCum and: i. nextPos := self initNextPos: end and: diameter1 and: diameter2. nextPos isNil not ifTrue: [self moveTo: nextPos. diameter1 := diameter2] ifFalse: [Dialog warn: ' cover = ', recCum asValue printString, '%'. i := 0]]]. step "Lancement pas a pas des actions pour chaque graine:" "Calcul d'indicateurs" self calcCoverByStrat. self covQI: self calcCovQI. "Mise en place des arbres" self strat > 4 ifTrue: [self locateTrees]. "Mise en place des arbustes" (self strat between: 1 and: 4) ifTrue: [(self ds ~= 'QI' and: [self ds ~= 'Bs']) ifTrue: [Seed totCov = self cover ifTrue: [self locateShrubs] ifFalse: [self locateOtherShrubs]]. (self ds = 'QI' or: [self ds = 'Bs']) ifTrue: [self locateQIShrubs]]. "Mise en place des herbacees" self strat = 0 ifTrue: [self locateGrass]. updateLitter: diameter | lit initc | "mise a jour des especes de la litiere" initc := self patch numCol. lit := self starter select: [:c | (c newid between: 1 and: 100) and: [ c numCol between: initc and: (initc + diameter -1)]] . lit do: [:c | c ds isNil ifTrue: [c ds: self ds] ifFalse: [c ss isNil ifTrue: [c ss: self ds]]]. CormasNS.Models.Segment.Seed dicoVF constituteDico | h uneSession answer resultQuery clef | "recherche dans DB_clump des donnees de VF dont on a besoin" self strat > 0 ifTrue: [ self strat > 4 ifTrue: [h := self max]. self strat = 1 ifTrue: [h := 25]. self strat = 2 ifTrue: [h := 50]. self strat = 3 ifTrue: [h := 75]. self strat = 4 ifTrue: [self max > 0 ifTrue: [h := self max] ifFalse: [h := 150]]. "ouverture de la session" uneSession := Segment uneConnexion getSession. "lancement de la requete SQL" uneSession prepare: 'SELECT T_VF.code_couche, T_VF.VF_lea_live, T_VF.VF_twi_02_live, T_VF.VF_leatwi_02_live, T_VF.VF_leatwi_02_dead, T_VF.VF_twi_26_live, T_VF.VF_twi_26_dead, T_VF.VF_twi_625_live, T_VF.VF_twi_625_dead FROM T_data INNER JOIN T_VF ON T_data.Code_data = T_VF.Code_vf WHERE (((T_data.Code_specie) like ' , self ds value printString, ') AND ((T_data.Height) like ', h value asInteger printString,' ) AND ((T_data.default)=1))'; execute. "reponse pour une graine" answer:=uneSession answer. resultQuery:= OrderedCollection new. resultQuery:= resultQuery, (answer upToEnd). resultQuery size = 0 ifTrue:[Dialog warn: 'No data found for ', self ds, ' of ', h value printString,' cm. please check in DBClump'. self halt]. "tout est stocke au fur et a mesure dans le dico dont la clef est la concatenation de espece et hauteur" clef := self ds, '_', h value asInteger printString. Segment dico add: clef -> resultQuery]. CormasNS.Models.Segment.Seed shapes calcClef: diffX and: diffY | Yclef Xclef clef | Yclef := (self patch numLine - diffY) asInteger. Yclef < 10 ifTrue: [Yclef := '0',Yclef value printString] ifFalse: [Yclef := Yclef value printString]. Xclef := (self patch numCol - diffX) asInteger. Xclef < 10 ifTrue: [Xclef := '0',Xclef value printString] ifFalse: [Xclef := Xclef value printString]. clef := Xclef , '_', Yclef. ^clef. coordShapeDB: diameter | uneSessionBord answerBord resultQueryBord code_shape uneSession answer resultQuery widthB nbC dicCoordCentre dicCoordBord uneSessionCentre answerCentre resultQueryCentre Yclef Xclef clef diffY diffX origine bas limitBord case nbCell newcase dicCoordSym limitSym limitBas count | "Recherche dans DB_clump des formes et positions de cube" self strat > 4 ifTrue: [bas := self max / 25]. self strat = 4 ifTrue: [self max > 0 ifTrue: [bas := self max / 25] ifFalse: [bas := 6]]. self strat = 3 ifTrue: [bas := 3]. self strat = 2 ifTrue: [bas := 2]. self strat = 1 ifTrue: [bas := 1]. origine:= self patch. diffY := origine numLine - 1. diffX := origine numCol - 1. "Requetes SQL pour constituer les dictionnaires de forme" uneSession := Segment uneConnexion getSession. uneSession prepare: 'SELECT DISTINCT T_shape.Width_bord, T_shape.Code_shape FROM T_data INNER JOIN T_shape ON T_data.Code_data = T_shape.Code_data WHERE ((T_data.Code_specie) like ', self ds value printString, ') AND ((T_data.Height) like ', (bas * 25) value asInteger printString, ') AND ((T_shape.Width_min) <= ', (diameter * 25) value asInteger printString, ') AND ((T_shape.Width_max)>=', (diameter * 25) value asInteger printString, ') AND ((T_data.default)=1)'; execute. answer:=uneSession answer. resultQuery:= OrderedCollection new. resultQuery:= resultQuery, (answer upToEnd). uneSession disconnect. resultQuery size = 0 ifTrue:[Dialog warn: 'No shape found. please check in DBClump'. self halt]. code_shape := ((resultQuery at:1) at:2). uneSessionBord := Segment uneConnexion getSession. uneSessionBord prepare: 'SELECT T_coord.X, T_coord.Y, T_coord.Code_pos, T_coord.Code_couche FROM T_coord INNER JOIN T_shape_coord ON T_coord.Code_coord = T_shape_coord.code_coord WHERE (((T_shape_coord.code_shape) like ', code_shape value printString,' and (T_coord.code_pos) = ''Bo'')) '; execute. answerBord:=uneSessionBord answer. resultQueryBord:= OrderedCollection new. resultQueryBord:= resultQueryBord, (answerBord upToEnd). uneSessionBord disconnect. uneSessionCentre := Segment uneConnexion getSession. uneSessionCentre prepare: 'SELECT T_coord.X, T_coord.Y, T_coord.Code_pos, T_coord.Code_couche FROM T_coord INNER JOIN T_shape_coord ON T_coord.Code_coord = T_shape_coord.code_coord WHERE ((T_shape_coord.code_shape) like ', code_shape value printString,' and(T_coord.code_pos) = ''Ce'') '; execute. answerCentre:=uneSessionCentre answer. resultQueryCentre:= OrderedCollection new. resultQueryCentre:= resultQueryCentre, (answerCentre upToEnd). uneSessionCentre disconnect. "Constitution des dictionnaires" dicCoordCentre := Dictionary new. dicCoordBord := Dictionary new. dicCoordSym := Dictionary new. resultQueryCentre isNil ifFalse: [resultQueryCentre do: [: each | dicCoordCentre add: (each at: 1), '_' ,(each at:2) -> (each at: 4)]]. resultQueryBord isNil ifFalse: [resultQueryBord do: [: each | dicCoordBord add: (each at: 1), '_' ,(each at:2) -> (each at: 4)]]. resultQueryBord isNil ifFalse: [resultQueryBord do: [: each | dicCoordSym add: (diameter - ((each at: 1) asNumber) + 1) value printString, '_' ,(each at:2) -> (each at: 4)]]. widthB := ((resultQuery at:1) at:1). widthB > 0 ifTrue: [ nbC:= diameter - (2*(widthB/ 25))] ifFalse: [ nbC:= diameter]. "1/ forme = bord + centre + sym" (nbC > 0 and: [ widthB>0] ) ifTrue: [ "Fabrication bord" limitBord := origine numCol + (widthB / 25) asInteger - 1. limitBas := origine numLine + bas - 1. nbCell := (((widthB/25) + 1) * bas). nbCell timesRepeat: [ (self patch numCol <= limitBord and: [self patch numLine <= limitBas]) ifTrue: [clef := self calcClef: diffX and: diffY. case := self starter select: [: c| c id = self patch id]. count := 0. dicCoordBord at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordBord at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. self moveTo: (case at:1) neighbourE] ifFalse: [(self patch numLine = limitBas) ifFalse: [newcase := self starter select: [: c| c id = ( (case at:1) id + 100 - (widthB/25 - 1) asInteger)]. self moveTo: (newcase at:1)] ifTrue: [newcase := self starter select: [: c| c id = ((case at:1) id + 1 - (100 *(bas-1) asInteger))]. self moveTo: (newcase at:1)]]]. "Fabrication centre" bas timesRepeat: [ clef := self calcClef: diffX and: diffY. case := self starter select: [: c| c id between: self patch id and: (self patch id + nbC - 1)]. count := 0. dicCoordCentre at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordCentre at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. newcase := self starter select: [: c| c id = ((case at:1) id + 100)]. self moveTo: (newcase at:1)]. case := self starter select: [: c| c id = ((newcase at:1) id + nbC - (100 *bas) asInteger)]. self moveTo: (case at:1). "Fabrication symetrique" limitSym := self patch numCol + (widthB / 25) asInteger - 1. nbCell timesRepeat: [ (self patch numCol <= limitSym and: [self patch numLine <= limitBas]) ifTrue: [Yclef := (self patch numLine - diffY) asInteger. Yclef < 10 ifTrue: [Yclef := '0',Yclef value printString] ifFalse: [Yclef := Yclef value printString]. Xclef := (self patch numCol - diffX) value printString. clef := Xclef , '_', Yclef. case := self starter select: [: c| c id = self patch id]. count := 0. dicCoordSym at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordSym at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. self moveTo: (case at:1) neighbourE] ifFalse: [(self patch numLine = limitBas) ifFalse: [newcase := self starter select: [: c| c id = ( (case at:1) id + 100 - (widthB/25 - 1) asInteger)]. self moveTo: (newcase at:1)]]]]. "2/ forme = bord + sym" (widthB>0 and: [nbC=0]) ifTrue: [ "Fabrication bord" limitBord := origine numCol + (widthB / 25) asInteger - 1. limitBas := origine numLine + bas - 1. nbCell := (((widthB/25) + 1) * bas). nbCell timesRepeat: [ (self patch numCol <= limitBord and: [self patch numLine <= limitBas]) ifTrue: [clef := self calcClef: diffX and: diffY. case := self starter select: [: c| c id = self patch id]. count := 0. dicCoordBord at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [ case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordBord at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. self moveTo: (case at:1) neighbourE] ifFalse: [(self patch numLine = limitBas) ifFalse: [newcase := self starter select: [: c| c id = ( (case at:1) id + 100 - (widthB/25 - 1) asInteger)]. self moveTo: (newcase at:1)] ifTrue: [newcase := self starter select: [: c| c id = ((case at:1) id + 1 - (100 *(bas-1) asInteger))]. self moveTo: (newcase at:1)]]]. "Fabrication symetrique" limitSym := self patch numCol + (widthB / 25) asInteger - 1. nbCell timesRepeat: [ (self patch numCol <= limitSym and: [self patch numLine <= limitBas]) ifTrue: [Yclef := (self patch numLine - diffY) asInteger. Yclef < 10 ifTrue: [Yclef := '0',Yclef value printString] ifFalse: [Yclef := Yclef value printString]. Xclef := (self patch numCol - diffX) value printString. clef := Xclef , '_', Yclef. case := self starter select: [: c| c id = self patch id]. count := 0. dicCoordSym at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [ case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordSym at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. self moveTo: (case at:1) neighbourE] ifFalse: [(self patch numLine = limitBas) ifFalse: [newcase := self starter select: [: c| c id = ( (case at:1) id + 100 - (widthB/25 - 1) asInteger)]. self moveTo: (newcase at:1)]]]]. "3/ forme = centre" (nbC > 0 and: [widthB=0]) ifTrue: [ bas timesRepeat: [ clef := self calcClef: diffX and: diffY. case := self starter select: [: c| c id between: self patch id and: (self patch id + nbC - 1)]. count := 0. dicCoordCentre at: clef ifAbsent: [count := 1]. count = 0 ifTrue: [ case do: [: c| c bufferState isNil ifTrue: [c bufferState: self ds. c pos: (dicCoordCentre at: clef). c seedstrat: self strat. c seedmax: self max] ifFalse: [c ss: self ds]]]. newcase := self starter select: [: c| c id = ((case at:1) id + 100)]. self moveTo: (newcase at:1)]]. "Retour a la case depart" case := self starter select: [: c| c id = origine id]. self moveTo: (case at:1). Litter CormasNS.Models.Segment CormasNS.Kernel.SpatialEntityAggregate false none ep1 ep2 ep31 ep32 ep33 ep34 ep35 ep36 ep37 ep38 ep39 ep310 ep315 ep320 ep325 SegmentCategory CurrentId CormasNS.Models.Segment.Litter false false As yet unclassified CormasNS.Models.Segment.Litter class id CurrentId ^CurrentId isNil ifTrue: [0] ifFalse: [CurrentId] CurrentId: x ^CurrentId := x CormasNS.Models.Segment.Litter accessing ep1 "taux de recouvrement de la litiere lu dans fichier input: ici moins de 50%" ^ep1 ep1: anObject ep1 := anObject ep2 "taux de recouvrement de la litiere lu dans fichier input: ici entre 50% et 75" ^ep2 ep2: anObject ep2 := anObject ep31 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 1cm" ^ep31 ep310 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 10cm" ep310 isNil ifTrue:[ep310 := 0]. ^ep310 ep310: anObject ep310 := anObject ep315 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 15cm" ep315 isNil ifTrue:[ep315 := 0]. ^ep315 ep315: anObject ep315 := anObject ep31: anObject ep31 := anObject ep32 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 2cm" ^ep32 ep320 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 20cm" ep320 isNil ifTrue:[ep320 := 0]. ^ep320 ep320: anObject ep320 := anObject ep32: anObject ep32 := anObject ep33 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 3cm" ^ep33 ep33: anObject ep33 := anObject ep34 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 4cm" ^ep34 ep34: anObject ep34 := anObject ep35 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 5cm" ^ep35 ep35: anObject ep35 := anObject ep36 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 6cm" ep36 isNil ifTrue:[ep36 := 0]. ^ep36 ep36: anObject ep36 := anObject ep37 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 7cm" ep37 isNil ifTrue:[ep37 := 0]. ^ep37 ep37: anObject ep37 := anObject ep38 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 8cm" ep38 isNil ifTrue:[ep38 := 0]. ^ep38 ep38: anObject ep38 := anObject ep39 "taux de recouvrement et epaisseur de la litiere lu dans fichier input: plus de 75 % et epaisseur vaut 9cm" ep39 isNil ifTrue:[ep39 := 0]. ^ep39 ep39: anObject ep39 := anObject CormasNS.Models.Segment.Litter update calculLitterThickness "Affectation de la litiere et de son epaisseur en fonction des strates dominantes" | temp33 temp30 collec1 collec2 caselit cpt collec3 collec4 | cpt := 0. temp33 := self ep33 + self ep34 + self ep35 + self ep36 + self ep37 + self ep38 + self ep39 + self ep310. collec1 := OrderedCollection new. collec2 := OrderedCollection new. collec3 := OrderedCollection new. collec4 := OrderedCollection new. collec1 addAll: (self components select: [:c | c domstrat = 3 and: [c ss ~= '0']]). collec1 isEmpty ifFalse: [collec1 size <= temp33 ifTrue: [cpt := collec1 size] ifFalse: [cpt := temp33]]. cpt timesRepeat: [caselit := Cormas selectRandomlyFrom: collec1. self ep310 > 0 ifTrue: [caselit comb: 10. self ep310: self ep310 - 1] ifFalse: [self ep39 > 0 ifTrue: [caselit comb: 9. self ep39: self ep39 - 1] ifFalse: [self ep38 > 0 ifTrue: [caselit comb: 8. self ep38: self ep38 - 1] ifFalse: [self ep37 > 0 ifTrue: [caselit comb: 7. self ep37: self ep37 - 1] ifFalse: [self ep36 > 0 ifTrue: [caselit comb: 6. self ep36: self ep36 - 1] ifFalse: [self ep35 > 0 ifTrue: [caselit comb: 5. self ep35: self ep35 - 1] ifFalse: [self ep34 > 0 ifTrue: [caselit comb: 4. self ep34: self ep34 - 1] ifFalse: [self ep33 > 0 ifTrue: [caselit comb: 3. self ep33: self ep33 - 1]]]]]]]]. collec1 remove: caselit]. "temp30 := self ep31 + self ep32 + self ep33 + self ep34 + self ep35 + self ep36 + self ep37 + self ep38 + self ep39 + self ep310." temp30 := self ep31 + self ep32 + self ep33 + self ep34 + self ep35 + self ep36 + self ep37 + self ep38 + self ep39 + self ep310 + self ep315 + self ep320. collec2 addAll: (self components select: [:c | c domstrat = 3 and: [c comb = 0]]). cpt := 0. collec2 isEmpty ifFalse: [collec2 size <= temp30 ifTrue: [cpt := collec2 size] ifFalse: [cpt := temp30]]. cpt timesRepeat: [caselit := Cormas selectRandomlyFrom: collec2. self putEp: caselit. collec2 remove: caselit]. collec2 isEmpty ifTrue: ["temp30 := self ep31 + self ep32 + self ep33 + self ep34 + self ep35 + self ep36 + self ep37 + self ep38 + self ep39 + self ep310." temp30 := self ep31 + self ep32 + self ep33 + self ep34 + self ep35 + self ep36 + self ep37 + self ep38 + self ep39 + self ep310 + self ep315 + self ep320. collec3 addAll: (self components select: [:c | c domstrat > 1 and: [c comb = 0]]). cpt := 0. collec3 isEmpty ifFalse: [collec3 size <= temp30 ifTrue: [cpt := collec3 size] ifFalse: [cpt := temp30]]. cpt timesRepeat: [caselit := Cormas selectRandomlyFrom: collec3. self putEp: caselit. collec3 remove: caselit]]. collec4 addAll: (self components select: [:c | c comb = 0]). cpt := collec4 size. cpt timesRepeat: [caselit := Cormas selectRandomlyFrom: collec4. (self ep31 > 0 or: [self ep32 > 0 or: [self ep33 > 0 or: [self ep34 > 0]]]) ifTrue: [self putEp: caselit] ifFalse: [self ep2 > 0 ifTrue: [caselit comb: 1. self ep2: self ep2 - 1] ifFalse: [caselit comb: 0]]. collec4 remove: caselit]. litterNat "Precision sur la nature de la litiere si pas d'info" | empty nat collec2 | empty := OrderedCollection new. empty addAll: (self components select: [:c | c comb > 0 and: [c ds = '0']]). empty size > 0 ifTrue: [nat:= (Dialog request: ('what is the main nature of the litter layer ?') asString). empty do: [:c | c ds: nat]]. collec2 := OrderedCollection new. collec2 addAll: (self components select: [:c | c comb = 0 and: [c ds ~= '0']]). collec2 isNil not ifTrue: [collec2 do: [:c | c ds:'0']]. putEp: caselit "Lien entre la variable 'comb' et l'epaisseur" self ep320 > 0 ifTrue: [caselit comb: 20. self ep320: self ep320 - 1] ifFalse: [self ep315 > 0 ifTrue: [caselit comb: 15. self ep315: self ep315 - 1] ifFalse: [self ep310 > 0 ifTrue: [caselit comb: 10. self ep310: self ep310 - 1] ifFalse: [self ep39 > 0 ifTrue: [caselit comb: 9. self ep39: self ep39 - 1] ifFalse: [self ep38 > 0 ifTrue: [caselit comb: 8. self ep38: self ep38 - 1] ifFalse: [self ep37 > 0 ifTrue: [caselit comb: 7. self ep37: self ep37 - 1] ifFalse: [self ep36 > 0 ifTrue: [caselit comb: 6. self ep36: self ep36 - 1] ifFalse: [self ep35 > 0 ifTrue: [caselit comb: 5. self ep35: self ep35 - 1] ifFalse: [self ep34 > 0 ifTrue: [caselit comb: 4. self ep34: self ep34 - 1] ifFalse: [self ep33 > 0 ifTrue: [caselit comb: 3. self ep33: self ep33 - 1] ifFalse: [self ep32 > 0 ifTrue: [caselit comb: 2. self ep32: self ep32 - 1] ifFalse: [self ep31 > 0 ifTrue: [caselit comb: 1. self ep31: self ep31 - 1]]]]]]]]]]]]. putLitterClass "Affectation finale de la valeur de l'epaisseur de la litiere en classes de 5 cm" | class0 class5 class10 class15 class20 | class0 := OrderedCollection new. class0 addAll: (self components select: [:c | c comb between: 0 and: 2]). class0 do: [:c | c comb: 0]. class5 := OrderedCollection new. class5 addAll: (self components select: [:c | c comb between: 3 and: 7]). class5 do: [:c | c comb: 5]. class10 := OrderedCollection new. class10 addAll: (self components select: [:c | c comb between: 8 and: 12]). class10 do: [:c | c comb: 10]. class15 := OrderedCollection new. class15 addAll: (self components select: [:c | c comb between: 12 and: 17]). class15 do: [:c | c comb: 15]. class20 := OrderedCollection new. class20 addAll: (self components select: [:c | c comb > 17]). class20 do: [:c | c comb: 20]. step "Deroulement des methodes de la litiere" self calculLitterThickness. self putLitterClass. self litterNat. CormasNS.Models.Segment.Litter init init: file "Lecture du fichier input pour la litiere et mise a jour des attributs" | line tmp item | super init. line := (file upTo: Character cr) readStream. [file atEnd] whileFalse: [line := (file upTo: Character cr) readStream. tmp := OrderedCollection new. [line atEnd] whileFalse: [item := line upTo: Character tab. tmp add: item]. self ep1: (tmp at:1) asNumber. self ep2: (tmp at:2) asNumber. self ep31: (tmp at:3) asNumber. self ep32: (tmp at:4) asNumber. self ep33: (tmp at:5) asNumber. self ep34: (tmp at:6) asNumber. self ep35: (tmp at:7) asNumber. self ep36: (tmp at:8) asNumber. self ep37: (tmp at:9) asNumber. self ep38: (tmp at:10) asNumber. self ep39: (tmp at:11) asNumber. self ep310: (tmp at:12) asNumber. "(tmp at:13 isNil) ifTrue: [self ep315: 0] ifFalse: [self ep315: (tmp at:13) asNumber]. (tmp at:14 isNil) ifTrue: [self ep320: 0] ifFalse: [self ep320: (tmp at:14) asNumber]. (tmp at:15 isNil) ifTrue: [self ep325: 0] ifFalse: [self ep325: (tmp at:15) asNumber]." self ep315: (tmp at:13) asNumber. self ep320: (tmp at:14) asNumber]. file close. initId self id: (self class CurrentId: self class CurrentId + 1) Cell CormasNS.Models.Segment CormasNS.Kernel.SpatialEntityCell false none newid litter ds ss domstrat seedstrat seedmax shade pos comb VF leaves all02 all02dead twigs02 twigs02dead twigs26 twigs26dead twigs625 twigs625dead numLigne SegmentCategory CurrentId CormasNS.Models.Segment.Cell false false As yet unclassified CormasNS.Models.Segment.Cell class id CurrentId ^CurrentId isNil ifTrue: [0] ifFalse: [CurrentId] CurrentId: x ^CurrentId := x CormasNS.Models.Segment.Cell accessing all02 "attribut contenant la valeur de VF des leaves and twigs between 0 and 2 mm " all02 isNil ifTrue:[all02 := 0]. ^all02 all02: anObject all02 := anObject all02dead "attribut contenant la valeur de VF des leaves and twigs dead between 0 and 2 mm " all02dead isNil ifTrue:[all02dead := 0]. ^all02dead all02dead: anObject all02dead := anObject comb "hauteur des herbes ou epaisseur de litiere" ^comb comb: anObject comb := anObject domstrat "indique la strate la plus haute qui domine la litiere" ^domstrat domstrat: anObject domstrat := anObject ds ^ds ds: anObject ds := anObject leaves "attribut contenant la valeur de VF des leaves" ^leaves leaves: anObject leaves := anObject litter ^litter litter: anObject litter := anObject newid "nouvel identifiant de cellule calcule du bas vers le haut" ^newid newid: anObject newid := anObject numLigne "nouveau numero de ligne utilise dans l'export" ^numLigne numLigne: anObject numLigne := anObject pos "position dans l'arbuste: B, C, ou T" ^pos pos: anObject pos := anObject seedmax "Getter accessor with default value = 0 " seedmax isNil ifTrue:[seedmax := 0]. ^seedmax seedmax: anObject seedmax := anObject seedstrat "numero de la strate de la graine qui a engendre une touffe " seedstrat isNil ifTrue:[seedstrat := nil]. ^seedstrat seedstrat: anObject seedstrat := anObject shade "caracterise les cellules sous les chenes verts si vaut 1" ^shade shade: anObject shade := anObject ss "especes secondaires" ^ss ss: anObject ss := anObject twigs02 "attribut contenant la valeur de VF des twigs between 0 and 2 mm " twigs02 isNil ifTrue:[twigs02 := 0]. ^twigs02 twigs02: anObject twigs02 := anObject twigs02dead "attribut contenant la valeur de VF twigs dead between 0 and 2 mm " twigs02dead isNil ifTrue:[twigs02dead := 0]. ^twigs02dead twigs02dead: anObject twigs02dead := anObject twigs26 "attribut contenant la valeur de VF twigs between 2 and 6 mm " twigs26 isNil ifTrue:[twigs26 := 0]. ^twigs26 twigs26: anObject twigs26 := anObject twigs26dead "attribut contenant la valeur de VF twigs dead between 2 and 6 mm " twigs26dead isNil ifTrue:[twigs26dead := 0]. ^twigs26dead twigs26dead: anObject twigs26dead := anObject twigs625 "attribut contenant la valeur de VF twigs dead between 6 and 25 mm " ^twigs625 twigs625: anObject twigs625 := anObject twigs625dead "Getter accessor with default value = 0 " twigs625dead isNil ifTrue:[twigs625dead := 0]. ^twigs625dead twigs625dead: anObject twigs625dead := anObject VF "valeur de la fraction volumique pour litiere et herbe" VF isNil ifTrue: [VF := 0]. ^VF VF: anObject VF := anObject CormasNS.Models.Segment.Cell update updateSpecies "mise a jour des attributs ds et ss a partir des valeurs stockees temporairement dans bufferState" (self bufferState isNil not and: [self bufferState ~= 'OO']) ifTrue: [ self ds isNil not ifFalse: [self ds: self bufferState] ifTrue: [self ss: self bufferState]]. self ds isNil ifTrue: [self ds: '0']. self ss isNil ifTrue: [self ss: '0']. updateVFherbe "attribution des fractions volumiques (x 10^6) " "HERBES : fraction volumique constante" (self ds = 'grass') ifTrue: [self VF: 1000]. updateVFligneux |clef h collec collec2 leaves_live twigs02_live leaves_twigs02_live leaves_twigs02_dead twigs26_live twigs26_dead twigs625_live twigs625_dead | "attribution des fractions volumiques (x 10^6) pour les LIGNEUX : en fonction de la position du cube dans la touffe et de la hauteur de l'arbuste" (self newid>200 and: [self ds~='0']) ifTrue: [ self seedstrat > 4 ifTrue: [h := self seedmax]. self seedstrat = 1 ifTrue: [h := 25]. self seedstrat = 2 ifTrue: [h := 50]. self seedstrat = 3 ifTrue: [h := 75]. self seedstrat = 4 ifTrue: [self seedmax > 0 ifTrue: [h := self seedmax] ifFalse: [h := 150]]. clef := self ds,'_', h value asInteger printString. collec:= Segment dico at: clef. collec2 := collec select: [:c | (c at:1) = self pos]. leaves_live:= ((collec2 at:1) at:2). self leaves: leaves_live. twigs02_live:= (collec2 at:1) at:3. self twigs02: twigs02_live. leaves_twigs02_live:= (collec2 at:1) at:4. self all02: leaves_twigs02_live. leaves_twigs02_dead:= (collec2 at:1) at:5. self all02dead: leaves_twigs02_dead. twigs26_live:= (collec2 at:1) at:6. self twigs26: twigs26_live. twigs26_dead:= (collec2 at:1) at:7. self twigs26dead: twigs26_dead. twigs625_live:= (collec2 at:1) at:8. self twigs625: twigs625_live. twigs625_dead:= (collec2 at:1) at:9. self twigs625dead: twigs625_dead]. updateVFlitiere "Attribution des fractions volumiques (x 10^6) " "LITIERE : France / Spain & Portugal" (self newid < 101and: [self ds ~= '0' and: [self comb ~= 0]]) ifTrue: [self VF: 21000]. (self newid < 101and: [((self ds at: 1) = $U or: [(self ds at: 1) =$E or: [(self ds at: 1) =$C]]) and: [self comb ~= 0]]) ifTrue: [self VF: 10000]. "LITIERE : Portugal pour Pinus Pinaster" (self newid < 101and: [self ds = 'PP' and: [self comb ~= 0]]) ifTrue: [self VF: 47394]. CormasNS.Models.Segment.Cell pov povCube "return a symbol or a ColorValue" self pos = 'T' ifTrue: [^#T]. self pos = 'C' ifTrue: [^#C]. self pos = 'B' ifTrue: [^#B]. ^ColorValue white povLitter "return a symbol or a ColorValue" self newid < 101 ifTrue: [ self comb = 0 ifTrue: [^#noLitter]. self comb = 5 ifTrue: [^#ep5cm]. self comb = 10 ifTrue: [^#ep10cm]. self comb = 15 ifTrue: [^#ep15cm]. self comb = 20 ifTrue: [^#ep20cm]]. povSecondarySpecies "return a symbol or a ColorValue" self ss = 'PP' ifTrue: [^#PP]. self ss = 'PH' ifTrue: [^#PH]. self ss = 'QI' ifTrue: [^#QI]. self ss = 'Qc' ifTrue: [^#Qc]. self ss = 'Ct' ifTrue: [^#Ct]. self ss = 'Eu' ifTrue: [^#Eu]. self ss = 'Eo' ifTrue: [^#Eo]. self ss = 'Um' ifTrue: [^#Um]. self ss = 'Ue' ifTrue: [^#Ue]. self ss = 'Bs' ifTrue: [^#Bs]. self ss = 'pt' ifTrue: [^#pt]. self ss = 'grass' ifTrue: [^#Grass]. "self bufferState = 'OO' ifTrue: [^#Shade]." povSpecies "return a symbol or a ColorValue" self ds = 'PP' ifTrue: [^#PP]. self ds = 'Ag' ifTrue: [^#Ag]. self ds = 'PH' ifTrue: [^#PH]. self ds = 'QI' ifTrue: [^#QI]. self ds = 'Qc' ifTrue: [^#Qc]. self ds = 'Bs' ifTrue: [^#Bs]. self ds = 'Ct' ifTrue: [^#Ct]. self ds = 'Eu' ifTrue: [^#Eu]. self ds = 'Eo' ifTrue: [^#Eo]. self ds = 'Ue' ifTrue: [^#Ue]. self ds = 'Um' ifTrue: [^#Um]. self ds = 'pt' ifTrue: [^#pt]. self ds = 'Jc' ifTrue: [^#Jc]. self ds = 'grass' ifTrue: [^#Grass]. ^ColorValue white povUnderQI "return a symbol or a ColorValue" self shade = 1 ifTrue: [^#Shade]. CormasNS.Models.Segment.Cell init init "Initialisation des attributs de cell" self shade: 0. self comb: 0. self domstrat: 0. self leaves: 0. self all02: 0. self all02dead: 0. self twigs02: 0. self twigs26: 0. self twigs02dead: 0. self twigs26dead: 0. self twigs625: 0. self twigs625dead: 0. initId self id: (self class CurrentId: self class CurrentId + 1) updateZ "Nouvelle numerotation des lignes de bas en haut pour l'export" self numLigne: (self newid - 101) // 100