	
	/**
     * Ce morceau de script sert a calculer la mortalite par peche par espece et par groupe d'age sur l'ensemble de la zone d'etude,
     * en minimisant la difference entre les captures d'ISIS et celles calculees a partir de l'equation de Baranov.
     * @param step
     * @param pop
     * @return Fishing mortality per group per year (computed in December)
     */
	 
	public MatrixND FishingMortalityPerGroup (TimeStep step, Population pop, ResultStorage resManager)throws TopiaException {   
		double Fgroup=0;
		double Ftemp=0;
		double Fpop=0;
		double Cgroup=0;
		double Ctot=0;
		double SumMtot=0;
		double Mpop=0;
		double Mgroup=0;
		double Mtot=0;
		double NgroupJan=0;
		double NgroupDec=0;
		double DeltaN=0;
		int  dim1;
		int  dim2;
		
		List<Population> populations = new ArrayList();
		populations.add(pop);
		List<PopulationGroup> groups = pop.getPopulationGroup();
					
		MatrixND tfgMatrix = MatrixFactory.getInstance().create(
		ResultName.MATRIX_FISHING_MORTALITY_PER_GROUP, 
		new List[]{populations, groups},  // On travaille sur les pops ET les groupes
		new String[]{n_("Population"), n_("Group")});
	
		
				
		for (PopulationGroup group : groups) {
			
			if (step.getMonth() == Month.DECEMBER){
			
				MatrixND catchPerStrategy = null;
						
				for (TimeStep loopstep = new TimeStep(step.getYear() * 12); loopstep.beforeOrEquals(step); loopstep=loopstep.next()){ 
					// On fait cette boucle pour contourner les aspects de cache qui font que les resultats ne sont pas recuperes 
					//s'ils ont deja ete calcules une fois (meme s'ils ont change depuis)
					// beforeOrEquals sert a bien prendre Decembre aussi
						
					MatrixND catchPerStrategyTemp = resManager.getMatrix(loopstep, pop, ResultName.MATRIX_CATCH_PER_STRATEGY_MET_PER_ZONE_POP);
					if (catchPerStrategy == null){
						catchPerStrategy = catchPerStrategyTemp.clone();
						// On clone la matrice car si on fait les operations sur celle contenue dans le cache on la modifie et donc on recupere des resultats faux.
					} 
					else {
						catchPerStrategy = catchPerStrategy.add(catchPerStrategyTemp); // Pour avoir la somme des captures sur les 12 mois
					}
				}
					
				log.info("catchPerStrategy = " + catchPerStrategy);
				catchPerStrategy = catchPerStrategy.sumOverDim(0); // Strategy
				catchPerStrategy = catchPerStrategy.sumOverDim(1); // Metier
				catchPerStrategy = catchPerStrategy.sumOverDim(3); // Zone : une pop peut avoir plusieurs zonespop dans ISIS
				List semgroup = catchPerStrategy.getSemantic(2);
				catchPerStrategy = catchPerStrategy.reduce(); // Enleve les dimensions de taille 1
				catchPerStrategy.setSemantic(0,semgroup); // Ne plait pas a Eric
				Cgroup = catchPerStrategy.getValue(group);
				log.info("Cgroup = " + Cgroup + "Year=" + step.getYear());
				log.info("catchPerStrategy = " + catchPerStrategy + "Year=" + step.getYear());
				
				MatrixND naturalDeathRatePop = pop.getNaturalDeathRateMatrix();
				naturalDeathRatePop = naturalDeathRatePop.meanOverDim(1); // moyenne sur Zone
				naturalDeathRatePop = naturalDeathRatePop.reduce(); // Enleve les dimensions de taille 1
				Mgroup = naturalDeathRatePop.getValue(group);
				log.info("Mgroup= " + Mgroup + "Year=" + step.getYear());
			
				MatrixND abundancePopJan = resManager.getMatrix(new TimeStep(12*step.getYear()), pop, ResultName.MATRIX_ABUNDANCE); // Le timestep 0 correspond a janvier de la premiere annee et les annees sont numerotees a partir de zero 				abundancePopJan = abundancePopJan.sumOverDim(1); // somme sur Zone
				abundancePopJan = abundancePopJan.reduce();
				NgroupJan = abundancePopJan.getValue(group);
				log.info("NgroupJan = " + NgroupJan + "Year=" + step.getYear());
				
				//Fgroup = RuleUtil.fmin(step,0.0,2.0,1.0e-10,Cgroup,Mgroup,NgroupJan);
				Fgroup = RuleUtil.fmin(0.0,2.0,1.0e-10, new FonctionObjectif_Baranov(Cgroup,Mgroup,NgroupJan)); // step ??
				
				log.info("Fgroup = " + Fgroup);
				
				tfgMatrix.setValue(pop, group, Fgroup); // Bien faire attention a l'endroit ou on met cette etape (quelle boucle) ?
			}
			else {
				//Fgroup = 0; // Ce n'est plus une valeur unique mais une matrice, est-ce que cette notation peut fonctionner ?
				tfgMatrix.setValue(pop, group, 0); // Bien faire attention a l'endroit ou on met cette etape (quelle boucle) ?
			}
			
		}	
		
		//tfgMatrix.setValue(pop, group, Fgroup); // Bien faire attention a l'endroit ou on met cette etape (quelle boucle) ?
		log.info("tfgMatrix = " + tfgMatrix);
		log.info("tfg.DimensionNames = " + Arrays.toString(tfgMatrix.getDimensionNames())); 
		log.info("tfg.Semantics = " + Arrays.toString(tfgMatrix.getSemantics())); 
			
		return tfgMatrix;		
	}
	
    /**
     * Ce morceau de script sert a calculer la mortalite par peche par espece et par groupe representatif a partir de la mortalite par 
	 * peche par groupe calculee precedemment.
     */
	 
	public MatrixND TotalFishingMortality (TimeStep step, Population pop, MatrixND FishingMortalityPerGroup)throws TopiaException { // Zone zone
		double Ftemp=0;
		double Fpop=0;
		double sum=0;
		//int Nbre;
	
		MatrixND tfmMatrix = FishingMortalityPerGroup.copy();
        tfmMatrix.setName(ResultName.MATRIX_TOTAL_FISHING_MORTALITY);
		log.info("tfmMatrix = " + tfmMatrix);
		
		List<Population> populations = new ArrayList();
		populations.add(pop);
		//log.info("pop = " + pop + "Year=" + step.getYear());
		
		//List<Population> populations = getPopulations(step);	
		List<PopulationGroup> groups = pop.getPopulationGroup();
		
   		
		
		int GpMin = pop.getGpMin();
		int GpMax = pop.getGpMax();
		int Nbre = GpMax - GpMin + 1;
		log.info("Nbre = " + Nbre);
		
		if (GpMin != GpMax){
			for (PopulationGroup group : groups) {
			   
				if (group.getId() == GpMin) {
					tfmMatrix = tfmMatrix.getSubMatrix(1, group, Nbre); // MatrixND getSubMatrix(int dim, Object, int nb)
					tfmMatrix = tfmMatrix.meanOverDim(1);
					tfmMatrix = tfmMatrix.reduce();
					log.info("tfm.DimensionNames = " + Arrays.toString(tfmMatrix.getDimensionNames())); 
					log.info("tfm.Semantics = " + Arrays.toString(tfmMatrix.getSemantics())); 
				}
			} 
		}
		else {				
				tfmMatrix = tfmMatrix.reduce();
				log.info("tfm.DimensionNames = " + Arrays.toString(tfmMatrix.getDimensionNames())); 
				log.info("tfm.Semantics = " + Arrays.toString(tfmMatrix.getSemantics())); 
			}
		
			
		return tfmMatrix;
		//return Fpop;
	}





