PageRenderTime 84ms CodeModel.GetById 18ms app.highlight 60ms RepoModel.GetById 1ms app.codeStats 0ms

/farmR/src/java/src/jfm/model/Location.java

https://code.google.com/p/javawfm/
Java | 352 lines | 267 code | 26 blank | 59 comment | 9 complexity | 5c675c319d4f7ec366dab904cbfebd3c MD5 | raw file
  1package jfm.model;
  2import java.util.*;
  3
  4import jfm.model.Types.VariableType;
  5import jfm.model.WorkableHoursCalculator;
  6import jfm.xml.XMLSyntaxException;
  7
  8/** Representation of physical characteristics of the farm such as soiltype and rainfall. 
  9 * Defines functions for calculating location dependent variables such as the number of workable hours 
 10 * available in particular periods of the year 
 11 * @author Ira Cooke 
 12 * \todo fix the Location class. Make it immutable (Important so that updates are done correctly) */
 13public final class Location extends VariableHolder { 
 14//	private double soiltype;
 15//	private double rainfall;
 16//	private double summernetevap;
 17	private final int numPeriods;
 18	private final double[] hoursCache;
 19	private final double[] freeTimeHoursCache;
 20
 21	public Location(double st,double rf,int numPeriods_){
 22		setVariable(VariableType.SOILTYPE,st);
 23		setVariable(VariableType.RAINFALL,rf);
 24		numPeriods=numPeriods_;
 25		hoursCache=new double[numPeriods];
 26		freeTimeHoursCache=new double[numPeriods];
 27		refreshHoursCache();
 28	}
 29	
 30	
 31	public Location copy(){
 32		return new Location(getVariable(VariableType.SOILTYPE),getVariable(VariableType.RAINFALL),numPeriods);
 33	}
 34	
 35	private static HashMap<Integer,double[] > freeTimeHoursMap = new HashMap<Integer,double[]>();
 36	static{
 37		double[] hours26=new double[26];		
 38		hours26[0]=80;		
 39		hours26[1]=80;
 40		hours26[2]=80;
 41		hours26[3]=80;
 42		hours26[4]=85;
 43		hours26[5]=90;
 44		hours26[6]=100;
 45		hours26[7]=110;
 46		hours26[8]=120;
 47		hours26[9]=120;
 48		hours26[10]=120;
 49		hours26[11]=120;
 50		hours26[12]=120;
 51		hours26[13]=120;
 52		hours26[14]=120;
 53		hours26[15]=120;
 54		hours26[16]=120;
 55		hours26[17]=120;
 56		hours26[18]=120;
 57		hours26[19]=110;
 58		hours26[20]=100;
 59		hours26[21]=90;
 60		hours26[22]=90;
 61		hours26[23]=90;
 62		hours26[24]=90;
 63		hours26[25]=90;
 64		double[] hours13=new double[13];
 65		for(int i=0;i<13;i++){
 66			hours13[i]=hours26[i*2]+hours26[i*2+1];
 67		}
 68		double[] hours2=new double[2];
 69		hours2[0]=140*13;
 70		hours2[1]=140*13;
 71
 72		freeTimeHoursMap.put(26, hours26);
 73		freeTimeHoursMap.put(13,hours13);
 74		freeTimeHoursMap.put(2, hours2);
 75	}
 76	
 77	private static HashMap<Integer,double[] > hoursMap = new HashMap<Integer,double[]>();
 78	static{
 79		double[] hours26=new double[26];
 80		double[] hours13=new double[13];
 81		double[] hours2=new double[2];
 82		/*
 83		hours26[0]=51;		
 84		hours26[1]=51;
 85		hours26[2]=50;
 86		hours26[3]=50;
 87		hours26[4]=78;
 88		hours26[5]=78;
 89		hours26[6]=88;
 90		hours26[7]=88;
 91		hours26[8]=118;
 92		hours26[9]=118;
 93		hours26[10]=120.4;
 94		hours26[11]=122.4;
 95		hours26[12]=125.4;
 96		hours26[13]=125.4;
 97		hours26[14]=118.4;
 98		hours26[15]=118.6;
 99		hours26[16]=110.6;
100		hours26[17]=110.6;
101		hours26[18]=110.6;
102		hours26[19]=91.0;
103		hours26[20]=79.8;
104		hours26[21]=69.5;
105		hours26[22]=56.3;
106		hours26[23]=36.1;
107		hours26[24]=36.9;
108		hours26[25]=36.7;
109		*/
110		
111		hours26[0]=0.0;		
112		hours26[1]=0.0;
113		hours26[2]=0.0;
114		hours26[3]=0.7;
115		hours26[4]=20.0;
116		hours26[5]=47.8;
117		hours26[6]=75.7;
118		hours26[7]=103.5;
119		hours26[8]=118.4;
120		hours26[9]=118.4;
121		hours26[10]=118.4;
122		hours26[11]=118.4;
123		hours26[12]=118.4;
124		hours26[13]=118.4;
125		hours26[14]=118.4;
126		hours26[15]=117.3;
127		hours26[16]=114.5;
128		hours26[17]=100.0;
129		hours26[18]=86.1;
130		hours26[19]=72.3;
131		hours26[20]=58.4;
132		hours26[21]=44.6;
133		hours26[22]=30.7;
134		hours26[23]=16.9;
135		hours26[24]=3.6;
136		hours26[25]=0.0;		
137		
138		for ( int i=0;i<13;i++){
139			hours13[i]=hours26[2*i]+hours26[2*i+1];
140		}
141		for( int i=0;i<2;i++){
142			hours2[i]=0;
143			for ( int j=0;j<13;j++){
144				hours2[i]+=hours26[i*13+j];
145			}
146		}
147		hoursMap.put(26, hours26);
148		hoursMap.put(13, hours13);
149		hoursMap.put(2, hours2);
150	}
151	public static HashMap<String,Integer> month=new HashMap<String,Integer>();
152	static {
153		month.put("Jan",0);
154		month.put("Feb",1);
155		month.put("Mar",2);
156		month.put("Apr",3);
157		month.put("May",4);
158		month.put("Jun",5);
159		month.put("Jul",6);
160		month.put("Aug",7);
161		month.put("Sep",8);
162		month.put("Oct",9);
163		month.put("Nov",10);
164		month.put("Dec",11);
165	}
166	
167	/** In order to provide compatibility with the WFM this class is needed. 
168	 * Each date represents the first day in a given period. The periods given are 
169	 * unfolded periodic .. in order to fold use period-(year-1)*26 */
170	public static ArrayList<GregorianCalendar> periods26=new ArrayList<GregorianCalendar>();
171	static {
172		periods26.add(new GregorianCalendar(2000,month.get("Jul"),16,0,0));//14
173		periods26.add(new GregorianCalendar(2000,month.get("Jul"),30,0,0));//15
174		periods26.add(new GregorianCalendar(2000,month.get("Aug"),13,0,0));//16
175		periods26.add(new GregorianCalendar(2000,month.get("Aug"),27,0,0));//17
176		periods26.add(new GregorianCalendar(2000,month.get("Sep"),10,0,0));//18
177		periods26.add(new GregorianCalendar(2000,month.get("Sep"),24,0,0));//19
178		periods26.add(new GregorianCalendar(2000,month.get("Oct"),8,0,0));//20
179		periods26.add(new GregorianCalendar(2000,month.get("Oct"),22,0,0));//21
180		periods26.add(new GregorianCalendar(2000,month.get("Nov"),5,0,0));//22
181		periods26.add(new GregorianCalendar(2000,month.get("Nov"),19,0,0));//23
182		periods26.add(new GregorianCalendar(2000,month.get("Dec"),3,0,0));//24
183		periods26.add(new GregorianCalendar(2000,month.get("Dec"),17,0,0));//25
184		periods26.add(new GregorianCalendar(2001,month.get("Jan"),1,0,0));//26
185		periods26.add(new GregorianCalendar(2001,month.get("Jan"),15,0,0));//27
186		periods26.add(new GregorianCalendar(2001,month.get("Jan"),29,0,0));//28
187		periods26.add(new GregorianCalendar(2001,month.get("Feb"),12,0,0));//29
188		periods26.add(new GregorianCalendar(2001,month.get("Feb"),26,0,0));//30
189		periods26.add(new GregorianCalendar(2001,month.get("Mar"),12,0,0));//31
190		periods26.add(new GregorianCalendar(2001,month.get("Mar"),26,0,0));//32
191		periods26.add(new GregorianCalendar(2001,month.get("Apr"),9,0,0));//33
192		periods26.add(new GregorianCalendar(2001,month.get("Apr"),23,0,0));//34
193		periods26.add(new GregorianCalendar(2001,month.get("May"),7,0,0));//35
194		periods26.add(new GregorianCalendar(2001,month.get("May"),21,0,0));//36
195		periods26.add(new GregorianCalendar(2001,month.get("Jun"),4,0,0));//37
196		periods26.add(new GregorianCalendar(2001,month.get("Jun"),18,0,0));//38
197		periods26.add(new GregorianCalendar(2001,month.get("Jul"),1,0,0));//39
198		periods26.add(new GregorianCalendar(2001,month.get("Jul"),16,0,0));//40
199		periods26.add(new GregorianCalendar(2001,month.get("Jul"),30,0,0));//41
200		periods26.add(new GregorianCalendar(2001,month.get("Aug"),13,0,0));//42
201		periods26.add(new GregorianCalendar(2001,month.get("Aug"),27,0,0));//43
202		periods26.add(new GregorianCalendar(2001,month.get("Sep"),10,0,0));//44
203		periods26.add(new GregorianCalendar(2001,month.get("Sep"),24,0,0));//45
204		periods26.add(new GregorianCalendar(2001,month.get("Oct"),8,0,0));//46
205		periods26.add(new GregorianCalendar(2001,month.get("Oct"),22,0,0));//47
206		periods26.add(new GregorianCalendar(2001,month.get("Nov"),5,0,0));//48
207		periods26.add(new GregorianCalendar(2001,month.get("Nov"),19,0,0));//49
208		periods26.add(new GregorianCalendar(2001,month.get("Dec"),3,0,0));//50
209		periods26.add(new GregorianCalendar(2001,month.get("Dec"),16,0,0));//51
210	}
211	
212	/** In order to provide compatibility with the WFM this class is needed. 
213	 * Each date represents the first day in a given period. The periods given are 
214	 * unfolded periodic .. in order to fold use period-(year-1)*26 */
215	public static ArrayList<GregorianCalendar> periods13=new ArrayList<GregorianCalendar>();
216	static {
217		periods13.add(new GregorianCalendar(2000,month.get("Jul"),16,0,0));//7
218		periods13.add(new GregorianCalendar(2000,month.get("Aug"),13,0,0));//8
219		periods13.add(new GregorianCalendar(2000,month.get("Sep"),10,0,0));//9
220		periods13.add(new GregorianCalendar(2000,month.get("Oct"),8,0,0));//10
221		periods13.add(new GregorianCalendar(2000,month.get("Nov"),5,0,0));//11
222		periods13.add(new GregorianCalendar(2000,month.get("Dec"),3,0,0));//12
223		periods13.add(new GregorianCalendar(2001,month.get("Jan"),1,0,0));//13
224		periods13.add(new GregorianCalendar(2001,month.get("Jan"),29,0,0));//14
225		periods13.add(new GregorianCalendar(2001,month.get("Feb"),26,0,0));//15
226		periods13.add(new GregorianCalendar(2001,month.get("Mar"),26,0,0));//16
227		periods13.add(new GregorianCalendar(2001,month.get("Apr"),23,0,0));//17
228		periods13.add(new GregorianCalendar(2001,month.get("May"),21,0,0));//18
229		periods13.add(new GregorianCalendar(2001,month.get("Jun"),18,0,0));//19
230		periods13.add(new GregorianCalendar(2001,month.get("Jul"),16,0,0));//20
231		periods13.add(new GregorianCalendar(2001,month.get("Aug"),13,0,0));//21
232		periods13.add(new GregorianCalendar(2001,month.get("Sep"),10,0,0));//22
233		periods13.add(new GregorianCalendar(2001,month.get("Oct"),8,0,0));//23
234		periods13.add(new GregorianCalendar(2001,month.get("Nov"),5,0,0));//24
235		periods13.add(new GregorianCalendar(2001,month.get("Dec"),3,0,0));//25
236	}
237	
238	public static ArrayList<GregorianCalendar> periods2=new ArrayList<GregorianCalendar>();
239	static {
240		periods2.add(new GregorianCalendar(2000,month.get("Jul"),16,0,0));//14
241		periods2.add(new GregorianCalendar(2001,month.get("Jan"),15,0,0));//27
242	}
243	
244	public static HashMap<Integer,ArrayList<GregorianCalendar>> periodsmap=new HashMap<Integer,ArrayList<GregorianCalendar>>();
245	static{
246		periodsmap.put(26,periods26);
247		periodsmap.put(13,periods13);
248		periodsmap.put(2,periods2);
249	}
250	public static int getWFMPeriod(GregorianCalendar caldate,int nperiods) throws XMLSyntaxException {
251		ArrayList<GregorianCalendar> periods = periodsmap.get(nperiods);		
252		int wfmp;
253		switch(nperiods){
254		case 26:
255			wfmp=14;
256			break;
257		case 13:
258			wfmp=7;
259			break;
260		default:
261			throw new XMLSyntaxException("Allowed numbers of periods are 2 26 or 13");
262		}
263		for(GregorianCalendar startperiod:periods ) {
264			if(!startperiod.before(caldate)){
265				return wfmp;
266			}
267			wfmp++;
268		}
269		throw new XMLSyntaxException("Date is outside WFM period range");
270	}
271	private double numberOfHoursInPeriodWithPeriods(int per,int numPeriods){
272		int numPer = periodsmap.get(numPeriods).size();
273		int offset=0;
274		switch(numPeriods){
275		case 26:
276			offset=12;
277			break;
278		case 13:
279			offset=6;
280			break;
281		case 2:
282			offset=1;
283			break;
284		default:
285			throw new Error("Allowed numbers of periods are 2 26 13");
286		}
287		per=per+offset;
288		GregorianCalendar dstart;
289		GregorianCalendar dfinish;
290//		if ( per > numPer-1 ){
291//			dstart=periodsmap.get(numPeriods).get(per-numPer);
292//		} else {
293		dstart = periodsmap.get(numPeriods).get(per);
294//		}
295		
296		
297		if ( per > numPer-2 ){
298			dfinish=periodsmap.get(numPeriods).get(offset);
299		} else {
300			dfinish = periodsmap.get(numPeriods).get(per+1);
301		}
302	//	System.out.println("Start p "+dstart.get(GregorianCalendar.DAY_OF_YEAR)+" end: "+dfinish.get(GregorianCalendar.DAY_OF_YEAR));
303		return WorkableHoursCalculator.workableHours(dstart.get(GregorianCalendar.DAY_OF_YEAR), dfinish.get(GregorianCalendar.DAY_OF_YEAR),getVariable(VariableType.SOILTYPE),getVariable(VariableType.RAINFALL));
304	}
305	
306	private void refreshHoursCache(){
307	//	System.out.println("Refreshing Hours Cache with: soil "+getVariable(VariableType.SOILTYPE)+" rf "+getVariable(VariableType.RAINFALL));
308		for(int i=0;i<hoursCache.length;i++){
309			// This is old code for when we needed to use fixed values 
310//			hoursCache[i]=hoursMap.get(numPeriods)[i];
311			
312			hoursCache[i]=numberOfHoursInPeriodWithPeriods(i,numPeriods);
313	//		System.out.println("Num Hours in period "+i+" "+hoursCache[i]+" "+freeTimeHoursMap.get(numPeriods)[i]);
314			freeTimeHoursCache[i]=freeTimeHoursMap.get(numPeriods)[i];
315		}
316		
317		
318		
319	}
320	/*
321	public double soiltype(){
322		return soiltype;
323	}
324	public double rainfall(){
325		return rainfall;
326	}*/
327
328	public double availableHours(int period){
329//		System.out.println("In period "+period+" we get "+hoursCache[period]);
330		return hoursCache[period];
331	}
332	public double availableFreeTimeHours(int period){
333		return freeTimeHoursCache[period];
334	}
335	
336	public void setSoilType(double soil){ 
337		setVariable(VariableType.SOILTYPE,soil);
338		refreshHoursCache();
339	}
340	public void setRainFall(double rain){ 
341		setVariable(VariableType.RAINFALL,rain);
342		refreshHoursCache();
343	}
344	public void set(double sl,double rn){
345		setVariable(VariableType.SOILTYPE,sl);
346		setVariable(VariableType.RAINFALL,rn);
347		refreshHoursCache();
348	}
349	
350	
351}
352