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