Suite

La ligne de mise en mémoire tampon dans ArcMap crée une mémoire tampon plus petite que prévu ?

La ligne de mise en mémoire tampon dans ArcMap crée une mémoire tampon plus petite que prévu ?


Lorsque je tamponne un point (point rouge sur l'image) de 3 miles, il fait 3 miles de tous les côtés. Lorsque je tamponne une ligne (ligne bleue sur l'image) de 3 miles, cela ressemble plus à 2,67 miles sur les côtés parallèles à la ligne. J'ai essayé différentes projections, mais j'obtiens fondamentalement le même résultat.

Des idées sur pourquoi cela se produit ou des solutions de contournement?


Lors de la mise en mémoire tampon (entre autres opérations liées à la distance) dans un géographique système de coordonnées, votre résultat peut apparaître ou être déformé en 2D car géographique est sur une sphère/ellipsoïde, pas à plat. Géographique utilise des degrés angulaires pour la mesure, et un degré de longitude peut varier considérablement en termes de distance en fonction de la latitude (qui est relativement cohérent). Ainsi, ce qui apparaît comme un cercle près de l'équateur serait une ellipse très écrasée près des pôles - voir l'indicatrice de Tissot.

Si vous êtes dans un projeté système de coordonnées (comme une zone State Plane), cette surface sphérique/3D a été aplatie, avec une certaine distorsion, en un plan 2D. Par conséquent, lorsque vous créez votre mémoire tampon, les résultats devraient être beaucoup plus cohérents en termes de distance - bien que peut-être inexacts sur de grandes distances. L'article Esri Understanding Geodesic Buffering donne des explications détaillées.

Il semble que vous ayez rencontré un problème avec le système de coordonnées de données d'origine étant géographique, la reprojection à la volée n'étant pas configurée correctement, ou la mémoire tampon utilisant le CRS d'origine (comme géographique) et non la trame de données (comme projeté). Notez également que si deux CRS ou projections ont des références différentes, vous devez également spécifier une transformation correcte pour la base de données à utiliser (il y a d'autres questions ici à ce sujet).

En rapport:


Tampon std::fstream vs tampon manuel (pourquoi gain 10x avec tampon manuel) ?

Mais ma mise en mémoire tampon manuelle améliore les performances d'un facteur 10 pour écrire un fichier de 100 Mo, et la mise en mémoire tampon fstream ne change rien par rapport à la situation normale (sans redéfinir un tampon).

Quelqu'un a-t-il une explication à cette situation ?

EDIT : Voici les nouveautés : un benchmark qui vient d'être fait sur un supercalculateur (architecture linux 64 bits, dure intel Xeon 8-core, système de fichiers Lustre et compilateurs, espérons-le bien configurés) (et je n'explique pas la raison de la "résonance" pour un buffer manuel de 1ko.)

EDIT 2 : Et la résonance à 1024 B (si quelqu'un a une idée là dessus, ça m'intéresse) :


fgets() utilise getc() en interne, pour lire un caractère à la fois, jusqu'à ce qu'il lise un saut de ligne ou atteigne la limite qui lui a été donnée. Chaque fois que getc() atteint la fin du tampon d'E/S, il remplit le tampon, il n'est donc pas limité à la taille définie par setvbuf() . La définition d'une petite taille de tampon le rend simplement moins efficace, mais ne modifie pas la quantité de données pouvant être lues.

setvbuf associe au fichier un buffer de taille 10.

Vous lisez le fichier avec fgets et essayez de lire 45 octets. Étant donné que le tampon du fichier est de taille 10 (et l'option _IOLBF), cela signifie que la lecture se fait de cette façon :

  1. Lire les octets 0-9 du fichier vers ma chaîne
  2. Lire les octets 10-19.
  3. Lire les octets 20-29.
  4. Lire les octets 30-39.
  5. Lit les octets 40-45 et s'arrête à

Au lieu d'utiliser un tampon par défaut et probablement de lire tous les octets à la fois (sans remplir le tampon)

La différence sans et avec setvbuf est,

fgets() lit 4096 mandrins d'octets à la fois. setvbuf est le moyen de contrôler et la taille du tampon lors de la lecture.

Vous définissez le mode de mise en mémoire tampon sur _IOLBF = Line Buffered, selon la page de manuel de setvbuf ". lorsqu'il s'agit d'une ligne tamponnée, les caractères sont enregistrés jusqu'à une nouvelle ligne. "

Ne devrait tamponner que 10 octets, mais fgets lirait toujours la ligne complète.

La mise en mémoire tampon signifie qu'en interne, les données sont lues dans le buff, lorsque le buff est plein ou mis en mémoire tampon en ligne également lorsqu'un saut de ligne est lu, le tampon est écrasé.


12 réponses 12

Cela a fait le travail (en 2012):

Je viens de chronométrer 8 Go en 36 secondes, soit environ 220 Mo/s et je pense que cela maximise mon SSD. Il convient également de noter que le code de la question utilisait un noyau à 100%, alors que ce code n'en utilise que 2 à 5%.

Mettre à jour: 5 ans ont passé, c'est 2017 maintenant. Les compilateurs, le matériel, les bibliothèques et mes exigences ont changé. C'est pourquoi j'ai apporté quelques modifications au code et fait de nouvelles mesures.

Ce code se compile avec Visual Studio 2017 et g++ 7.2.0 (une nouvelle exigence). J'ai exécuté le code avec deux configurations :

  • Ordinateur portable, Core i7, SSD, Ubuntu 16.04, g++ Version 7.2.0 avec -std=c++11 -march=native -O3
  • Ordinateur de bureau, Core i7, SSD, Windows 10, Visual Studio 2017 Version 15.3.1 avec /Ox /Ob2 /Oi /Ot /GT /GL /Gy

Ce qui a donné les mesures suivantes (après avoir abandonné les valeurs pour 1 Mo, car elles étaient des valeurs aberrantes évidentes): Les deux fois, option1 et option3 maximisent mon SSD. Je ne m'attendais pas à ce que cela se produise, car option2 était le code le plus rapide sur mon ancienne machine à l'époque.

TLDR: Mes mesures indiquent d'utiliser std::fstream sur FILE .

Essayez ce qui suit, dans l'ordre :

Taille de tampon plus petite. L'écriture

2 Mio à la fois pourraient être un bon début. Sur mon dernier ordinateur portable,

512 KiB était le sweet spot, mais je n'ai pas encore testé sur mon SSD.

Noter: J'ai remarqué que les très gros tampons ont tendance à diminuer performance. J'ai remarqué des pertes de vitesse avec l'utilisation de tampons de 16 Mio au lieu de 512 Kio auparavant.

Utilisez _open (ou _topen si vous voulez être correct pour Windows) pour ouvrir le fichier, puis utilisez _write . Cette volonté Probablement éviter beaucoup de mise en mémoire tampon, mais ce n'est pas certain.

Utilisation de fonctions spécifiques à Windows telles que CreateFile et WriteFile . Cela évitera toute mise en mémoire tampon dans la bibliothèque standard.

Je ne vois aucune différence entre std::stream/FILE/device. Entre la mise en mémoire tampon et la non mise en mémoire tampon.

  • Les disques SSD "ont tendance" à ralentir (taux de transfert inférieurs) au fur et à mesure qu'ils se remplissent.
  • Les disques SSD "ont tendance" à ralentir (taux de transfert inférieurs) à mesure qu'ils vieillissent (en raison de bits qui ne fonctionnent pas).

Je vois le code s'exécuter en 63 secondes.
Ainsi un taux de transfert de : 260M/s (mon SSD a l'air légèrement plus rapide que le vôtre).

Je n'obtiens aucune augmentation en déplaçant vers FILE* à partir de std::fstream.

Ainsi, le flux C++ fonctionne aussi vite que la bibliothèque sous-jacente le permet.

Mais je pense qu'il est injuste de comparer le système d'exploitation à une application construite sur le système d'exploitation. L'application ne peut faire aucune hypothèse (elle ne sait pas que les disques sont SSD) et utilise donc les mécanismes de fichiers du système d'exploitation pour le transfert.

Alors que le système d'exploitation n'a pas besoin de faire d'hypothèses. Il peut indiquer les types de lecteurs impliqués et utiliser la technique optimale pour transférer les données. Dans ce cas, un transfert direct de mémoire à mémoire. Essayez d'écrire un programme qui copie 80 Go d'un emplacement en mémoire à un autre et voyez à quelle vitesse c'est.

J'ai modifié mon code pour utiliser les appels de niveau inférieur :
c'est-à-dire pas de mise en mémoire tampon.

REMARQUE: Mon disque est un disque SSD si vous avez un disque normal, vous pouvez voir une différence entre les deux techniques ci-dessus. Mais comme je m'y attendais, la non mise en mémoire tampon et la mise en mémoire tampon (lors de l'écriture de gros morceaux supérieurs à la taille du tampon) ne font aucune différence.

Edit 2 :

Avez-vous essayé la méthode la plus rapide pour copier des fichiers en C++

La meilleure solution est d'implémenter une écriture asynchrone avec double buffering.

Le « F » représente le temps de remplissage du tampon et le « W » représente le temps d'écriture du tampon sur le disque. Donc, le problème de perdre du temps entre l'écriture de tampons dans un fichier. Cependant, en implémentant l'écriture sur un thread séparé, vous pouvez commencer à remplir le tampon suivant tout de suite comme ceci :

F - remplissage du 1er tampon
f - remplissage du 2ème tampon
W - écriture du 1er tampon dans le fichier
w - écriture du 2ème tampon dans le fichier
_ - attendre pendant que l'opération est terminée

Cette approche avec des échanges de tampons est très utile lorsque le remplissage d'un tampon nécessite des calculs plus complexes (donc plus de temps). J'implémente toujours une classe CSequentialStreamWriter qui cache l'écriture asynchrone à l'intérieur, donc pour l'utilisateur final, l'interface n'a que des fonctions d'écriture.

Et la taille de la mémoire tampon doit être un multiple de la taille du cluster de disques. Sinon, vous vous retrouverez avec des performances médiocres en écrivant un seul tampon sur 2 clusters de disques adjacents.

Écriture du dernier tampon.
Lorsque vous appelez la fonction Write pour la dernière fois, vous devez vous assurer que le tampon actuel est en cours de remplissage doit également être écrit sur le disque. Ainsi, CSequentialStreamWriter devrait avoir une méthode distincte, disons Finalize (vidage final du tampon), qui devrait écrire sur le disque la dernière partie des données.

La gestion des erreurs.
Alors que le code commence à remplir le 2ème tampon et que le 1er est écrit sur un thread séparé, mais que l'écriture échoue pour une raison quelconque, le thread principal doit être conscient de cet échec.

Supposons que l'interface d'un CSequentialStreamWriter a la fonction Write renvoie bool ou lève une exception, ayant ainsi une erreur sur un thread séparé, vous devez vous souvenir de cet état, donc la prochaine fois que vous appelez Write ou Finilize sur le thread principal, la méthode retournera False ou lèvera une exception. Et peu importe à quel moment vous avez cessé de remplir un tampon, même si vous avez écrit des données après l'échec - le fichier serait très probablement corrompu et inutile.


Méthodes

Équations du modèle

(1) (2)

Représentation du flux

Nous avons modélisé le flux dans la boîte comme une combinaison de flux moyen et de marée, de telle sorte que , avec des vitesses vers la terre positives et des vitesses vers la mer négatives. Vitesse moyenne moyenne dans le temps, , a été fixée à −0,01 ou −0,05 m/s parce que cela limite la majeure partie de la plage des vitesses moyennes observées dans les herbiers marins (annexe S1 : tableau S1). Vitesse de marée, vousmarée(t), a été modélisé en fonction de la profondeur de l'eau. Nous avons supposé un débit moyen moyen en profondeur négatif (vers la mer) dans notre prairie de zostère marine peu profonde en raison de la structure latérale typique de la circulation estuarienne moyenne dans les estuaires positifs (l'eau de l'océan est plus dense que l'eau estuarienne), qui se caractérise par un écoulement net vers la terre dans les régions plus profondes et vers la mer net. dans les régions moins profondes (Geyer et Maccready 2014 ). Alors que des parties de l'intérieur de la baie de Tomales deviennent hypersalines à l'automne, une grande partie de la baie maintient un gradient de densité positif tout au long des mois d'été en raison du chauffage solaire (un « estuaire thermique » Largier et al. 1996 ), justifiant les hypothèses de flux net vers la mer le long des rives de l'estuaire où se trouvent les herbiers de zostère.

Nous avons modélisé le flux de marée, vousmarée(t), en fonction de l'évolution de la profondeur de l'eau, vousmarée(t) = dh(t + )/dt où est un coefficient sans dimension proportionnel à l'amplitude de la vitesse moyenne (). Les valeurs de n'ont pas été choisies pour représenter une relation physique particulière entre le débit de marée et le débit moyen, mais ont plutôt été choisies dans un simple effort pour générer des débits moyens réversibles (c. vous(t) > 0 et vous(t) < 0) avec une plage de vitesse de marée environ quatre fois plus grande que l'amplitude de la vitesse moyenne moyenne dans le temps (). Nous avons représenté le décalage de phase entre le flux de marée et les changements de profondeur d'eau avec . Nous avons utilisé = 0 h pour représenter une onde stationnaire et = −3 h pour représenter une onde progressive.

Chimie aux limites et configurations de modèles

Chimie de l'eau aux conditions limites, DICdans, et TAdans, ont été simulés à l'aide d'estimations estuariennes et océaniques basées sur des observations de la baie Tomales et des eaux côtières adjacentes (Smith et Hollibaugh 1997 , Feely et al. 2016 ). Afin de mieux comprendre comment les conditions hydrodynamiques affectent le potentiel tampon de la zostère, nous avons considéré deux ensembles de conditions aux limites. Dans la première configuration du modèle, nous avons retenu l'océanique (DICocéan et TAocéan) et l'estuaire (DICestuaire et TAestuaire) conditions aux limites constantes (ci-après dénommées « limites fixes »). Cette configuration de modèle a simulé une prairie de zostère marine où les volumes des réservoirs océaniques et estuariens de chaque côté de la « boîte » de la prairie de zostère sont grands par rapport au volume d'eau au-dessus de la prairie (c.-à-d. « à l'intérieur de la boîte »). La configuration des limites fixes a simulé une condition où toute modification biogéochimique de l'eau de mer dans la prairie n'affecte pas les réservoirs limites. Sous ces limites fixes, lors d'une marée montante, les eaux océaniques étaient advectées dans la boîte, et à marée descendante, les eaux estuariennes étaient advectées dans la boîte (Fig. 1).

Dans la deuxième configuration du modèle, nous avons permis à la prairie de zostères d'échanger de l'eau avec une boîte latérale océanique et une boîte latérale estuarienne de volume égal à la prairie de zostère (indices système d'exploitation et es, respectivement, ci-après dénommés « boîtes latérales »). La configuration des boîtes latérales a été mise en place pour simuler des conditions où l'eau qui passe au-dessus de la prairie de zostère ne provient pas de réservoirs infiniment grands sur les côtés de la prairie, mais plutôt de volumes finis d'eau susceptibles de se modifier eux-mêmes par advection de la prairie de zostère. . Cette configuration modèle fournit un terrain d'entente entre la configuration à limites fixes, où la chimie des carbonates des réservoirs océanique et estuarien est fixe, et un système fermé sans advection où tous les changements chimiques de l'eau dans la zone de zostère marine proviennent de la photosynthèse et de la respiration.

(3)

Les équations de bilan massique pour les boîtes latérales décrivent les flux d'advection des deux limites (selon la directionnalité du flux) et sont analogues aux termes de flux advectif sur les bilans de masse DIC et TA pour la boîte de zostère marine. Nous n'avons pris en compte aucun flux de carbone provenant de la production localisée dans les boîtes latérales (représentées sur la figure 1b par l'absence de zostère dans les boîtes latérales). Lorsque l'eau s'écoule de l'océan vers l'estuaire (vous(t) > 0), l'eau contenue dans la boîte latérale océanique s'advecte dans la boîte de prairie et la boîte de prairie advec son eau biogéochimiquement modifiée dans la boîte latérale estuarienne. Lorsque le flux s'inverse de telle sorte que l'eau s'écoule de l'estuaire vers l'océan (vous(t) < 0), l'eau dans la boîte latérale estuarienne s'advecte dans la boîte de prairie et la boîte de prairie advec son eau biogéochimiquement modifiée vers la boîte latérale océanique. Reconnaissant que les boîtes latérales elles-mêmes sont affectées par l'advection des deux limites, nous avons décidé d'advecter les réservoirs estuariens et océaniques statiques dans les boîtes latérales respectives en fonction de la direction du flux (c.océan et TAocéan advect dans la boîte latérale océanique lorsque vous(t) > 0 DICestuaire et TAestuaire advect dans la boîte latérale de l'estuaire lorsque vous(t) < 0). Notez que lorsque vous(t) < 0, nous avons utilisé |vous(t)| dans les équations d'advection-réaction afin que le gradient de concentration puisse toujours être présenté comme entrant-sortant.

Photosynthèse et taux de respiration

Taux de photosynthèse brute intégrés verticalement, Pg, et la respiration, R, par la population de zostères marines ont été paramétrés en fonction de l'abondance des zostères marines, de l'irradiance de downwelling et de la chimie des carbonates sur la base d'une série de simulations de modèles calibrées pour la baie Tomales à l'aide du modèle bio-optique de zostère marine GrassLight (Zimmerman et al. 2015 ). Nous avons approximé l'abondance de la zostère marine à l'aide d'un indice de surface foliaire unilatéral (LAI = m 2 feuille/m 2 de fond marin) car il fournit un lien étroit entre les propriétés optiques des feuilles et les taux métaboliques spécifiques à la biomasse (Zimmerman 2006). L'irradiance solaire entrante au sommet de la canopée de zostère marine a été modélisée sur la base de l'irradiance solaire entrante modélisée à la surface de l'eau et du coefficient d'atténuation de la lumière, K, spécifique aux propriétés bio-optiques de la baie de Tomales (voir l'annexe S1 pour des informations supplémentaires sur l'irradiance solaire et K calculs). Nous avons modélisé la distribution verticale de la biomasse des feuilles de zostère marine dans la canopée en fonction sigmoïde de la hauteur à une distance de 1 m au-dessus du fond marin, avec des feuilles orientées à 15° de la verticale (Zimmerman 2003), de sorte que la hauteur de la canopée réalisée était de 0,97 m. . Lorsque la profondeur de l'eau était inférieure à la hauteur du couvert de zostère marine, la fraction du couvert de zostère marine au-dessus de l'eau était présumée flotter à la surface de l'eau. Détails sur la dépendance de Pg et R sur la chimie des carbonates dans l'herbier se trouve à l'annexe S1.

Étant donné que le but de cette étude est d'évaluer et de quantifier le potentiel tampon offert par la zostère marine, les taux métaboliques ne concernent que la zostère marine et n'incluent pas les contributions d'autres processus benthiques ou de la colonne d'eau (voir la discussion pour plus de détails). La dépendance partielle de Pg et R sur la chimie des carbonates conduit à un couplage entre le métabolisme de la zostère et la chimie de l'eau sus-jacente de telle sorte que le métabolisme de la zostère est une fonction de la chimie de l'eau sus-jacente et que la chimie de l'eau sus-jacente est une fonction du métabolisme de la zostère. Des détails sur les paramétrisations du taux métabolique sont fournis à l'annexe S1.

Autres flux de carbone

Nous n'avons pas inclus la calcification nette (précipitations moins dissolution du carbonate de calcium) dans nos bilans massiques pour le DIC et le TA car il ne s'agit généralement pas d'un processus biogéochimiquement important dans la baie de Tomales (Smith et al. 1991). Étant donné que la modification biogéochimique de l'AT dans l'herbier n'est contrôlée que par RAT et production biologique nette (NP = PgR), la modification locale de l'AT dans la prairie de zostère est généralement faible (<20 μmol/kg). Cependant, nous avons conservé le bilan massique TA dans le modèle pour des raisons d'exhaustivité et de portabilité vers d'autres systèmes. En particulier, le modèle est applicable aux systèmes tropicaux, où la calcification nette est un processus biogéochimique important. De plus, des calculs préliminaires ont montré que les flux de gaz air/mer étaient bien inférieurs à ceux dérivés du métabolisme net (<1% de PgR). Les flux de gaz air/mer ont donc été exclus de ces calculs de bilan massique.

Effet tampon (capacité tampon)

Nous avons défini l'effet tampon, ou la capacité tampon, comme le changement dans la chimie des carbonates entre une simulation de contrôle sans zostère (représentée par le réglage LAI = 0) et une simulation de modèle qui contient de la zostère à une densité donnée (représentée par LAI > 0). Nous avons calculé les effets tampons après avoir maintenu constants tous les autres paramètres du modèle (p. ex., conditions aux limites, saison, vitesse d'écoulement, phasage des marées, etc.) entre le modèle témoin et le modèle peuplé de zostères, de sorte que les différences dans la chimie des carbonates sont uniquement attribuables à la zostère. densité dans la boîte du modèle.

Résolution du modèle

Les simulations du modèle ont été exécutées à un pas de temps de 15 minutes dans lequel chaque pas de temps résout complètement la chimie des carbonates dans le pré (ainsi que la chimie des carbonates dans les boîtes latérales lorsque le modèle est configuré pour fonctionner avec des boîtes latérales), ainsi que la zostère prairie simulée Pg et R. La durée du pas de temps du modèle est suffisante pour capturer la variation intra-journalière de la disponibilité de la lumière causée par la rotation de la Terre. Mais le modèle n'inclut pas la variation à l'échelle météorologique de la disponibilité de la lumière résultant des nuages. Le modèle inclut les fluctuations de la profondeur de l'eau entraînées par les marées mixtes semi-diurnes.

Baie de Tomales

Caractéristiques du site

Nous avons choisi de paramétrer notre modèle généralisé pour une prairie de zostère marine à Tomales Bay, Californie, USA (Fig. 2). Située au nord de San Francisco, Tomales Bay est une baie peu profonde et très unidirectionnelle (

1 km de large) estuaire semi-fermé de la côte ouest formé dans une vallée du rift noyée de la faille de San Andreas (Hearn et Largier 1997 Fig. 2a). Cette région côtière connaît certains des vents favorables d'upwelling les plus forts le long de la côte ouest de l'Amérique du Nord (Largier et al. 2006 ). L'eau douce pénètre dans la baie par son extrémité sud (Lagunitas Creek) et son côté est (Walker Creek), principalement pendant les mois d'hiver. Les eaux de la baie Tomales subissent un large éventail de conditions physiques et chimiques, car de l'eau nouvellement remontée est introduite dans la baie et commence à subir des modifications biogéochimiques et physiques. La baie de Tomales est le site d'une grande économie d'aquaculture de bivalves (Dumbauld et al. 2009 ), de sorte que les impacts de l'acidification des océans sont susceptibles d'avoir des ramifications économiques, ainsi qu'écologiques.

Les herbiers de zostère marine dans la partie supérieure de la baie Tomales sont répartis en environ 25 parcelles entre l'embouchure de la baie et l'île Hog, située

6 km de l'embouchure de la baie (Fig. 2b). Analyse manuelle des dimensions des patchs dans la partie supérieure de Tomales Bay à l'aide de Google Earth Pro1 1 https://www.google.com/earth/desktop/
a révélé des dimensions médianes de 304 m (axe le plus long) × 38 m (axe orthogonal), avec une zone de patch médiane de

1 ha, qui couvre une superficie totale d'environ 40 ha. Cela représente environ 10 % de la superficie de la baie entre l'embouchure et l'île Hog.

Variabilité saisonnière

Nous avons mené une série de simulations de 30 jours conçues pour simuler la remontée d'eau estivale, la relaxation estivale et les conditions hivernales de non remontée d'eau dans une prairie de zostère marine dans la partie supérieure de la baie Tomales. Les herbiers de zostère marine de cette région subissent un forçage provenant à la fois de l'embouchure (eaux de source océanique) et de la tête (eaux de source estuarienne) de la baie (Largier et al. 1997 , Smith et Hollibaugh 1997 ). Ce forçage nous a permis de tester des hypothèses sur les effets de la chimie carbonatée des eaux incidentes sur la capacité tampon de la zostère marine. Nous avons choisi de simuler trois conditions saisonnières (upwelling estival, relaxation estivale et hivernale) car elles offrent un contraste maximal dans les conditions environnementales (température, salinité, chimie des carbonates et lumière) rencontrées par la zostère marine de la baie Tomales au cours d'un cycle annuel. Nous avons utilisé l'ensemble de données chimiques bimensuelles de la colonne d'eau de Smith et Hollibaugh (1997) recueillies dans la partie intérieure à moyenne de la baie de Tomales pour construire des cycles annuels composites de température, de salinité et de chimie de l'eau, à partir desquels nous avons choisi nos valeurs saisonnières. Les dates des simulations saisonnières ont été choisies en sélectionnant les valeurs maximales et minimales pour le paramétrage de l'indice d'upwelling de Bakun fourni par Smith et Hollibaugh pour Tomales Bay (1997), qu'ils ont utilisées comme approximation de la force du cycle annuel d'upwelling. Ces maxima et minima étaient respectivement les jours calendaires 198 et 16. Par conséquent, les simulations des modèles d'été et d'hiver ont commencé respectivement aux jours calendaires 183 et 1.

Valeurs estivales sélectionnées du pHocéan représentent une tentative de délimiter la plage de pH attendue le long de la côte entre les périodes d'upwelling et de relaxation (Feely et al. 2016 ). pH hivernalocéan a été pris comme 8.1 pour représenter le retour des eaux du courant de Californie au large de la côte en l'absence de remontée d'eau (Feely et al. 2016 ). Valeurs pour le pHestuaire et TAestuaire étaient fondées sur le relevé composite sur 8 ans de Smith et Hollibaugh (1997). CIDocéan a été calculé à partir du pHocéan et TAocéan et DICestuaire a été calculé à partir du pHestuaire et TAestuaire (voir le code modèle pour plus de détails sur les calculs de la chimie des carbonates). Nous avons tenu TAocéan constant et égal à TAestuaire pour éviter l'influence confondante des flux de TA advectifs sur notre interprétation des simulations du modèle. Enfin, nous avons contrôlé l'atténuation lumineuse dans la colonne d'eau du modèle de boîte à l'aide d'un coefficient d'atténuation lumineuse, K, qui a été paramétré dans GrassLight. Pour paramétrer l'été K valeur, nous avons supposé la chlorophylle d'été une (chl une) était de 8 μg/L et la concentration totale de matières en suspension (TSM) était de 4 mg/L. Nous avons supposé le chl d'hiver une la concentration était de 5 μg/L et la concentration TSM était de 4 mg/L pour paramétrer l'hiver K valeur (voir l'annexe S1 pour plus de détails). Bien que chl une et TSM ont été utilisés pour informer les estimations des propriétés bio-optiques de la colonne d'eau, ils n'ont pas été utilisés directement dans les calculs du modèle de boîte.

Nous avons maintenu la température et la salinité, et donc ρ, constants dans chaque simulation saisonnière, en ne les faisant varier qu'à travers les scénarios saisonniers conformément au tableau 1. Nous avons également répété chaque simulation quatre fois, en faisant varier le phasage de la vitesse entrante par rapport aux changements de hauteur de marée () de 0 à -3 h afin de capturer toutes les interactions possibles cycle de marée-cycle journalier. Les résultats de ces quatre simulations ont été agrégés pour représenter une distribution plus large de la modification du pH attendue dans chaque scénario de modélisation (Fig. 3).

Saison Commencer le jour calendaire T (°C) Salinité pHocéan ATocéan pHestuaire ATestuaire
Été (remontée d'eau) 183 18 35 7.7 2,300 8.0 2,300
Été (détente) 183 18 35 8.0 2,300 8.0 2,300
L'hiver 1 11 28 8.1 2,200 8.2 2,200

Remarques

(a, d) la profondeur de l'eau, (b, e) la vitesse et (c, f) l'irradiance solaire (rayonnement photosynthétiquement disponible, PAR) au sommet de la canopée de zostère pour l'été (a-c) et l'hiver (d-f ) des scénarios de modélisation. Les lignes pleines dans les panneaux b) et e) montrent les séries temporelles de vitesse pour = −0,01 m/s et les lignes pointillées dans les panneaux b) et e) montrent les séries temporelles de vitesse pour = −0,05 m/s. Le déphasage, , est exprimé en heures.

Code du modèle

Nous avons effectué toutes les simulations de modèle de boîte, l'analyse des données et le traçage dans R (R Core Team 2016). Nous avons utilisé le package deSolve pour les équations de bilan massique (Soetaert et al. 2010 ). Nous avons utilisé le package seacarb pour tous les calculs de chimie des carbonates avec des paramètres par défaut pour toutes les constantes d'équilibre (Gattuso et al. 2016). Nous avons supposé des effets de pression négligeables et des contributions des nitrates, des silicates et des phosphates dans nos calculs de chimie des carbonates. Toutes les figures du texte principal et de l'annexe S1 ont été développées à l'aide du package ggplot2 (Wickham 2009 ).


3. MÉTHODOLOGIE

Dans cette section, nous décrivons le processus de recherche en science de la conception exploratoire (Holmström et al., 2009) qui a créé la pratique du frontlog, y compris la façon dont nous anticipons les résultats de la mise en œuvre et évaluons notre conception dans le cadre du cas. La recherche en science de la conception normale (van Aken, Chandrasekaran et Halman, 2016) se concentre sur l'amélioration des pratiques, en mettant l'accent sur les tests sur le terrain et la mise en œuvre. La science de la conception exploratoire partage l'intérêt d'améliorer la pratique, cependant, l'accent est mis sur le recadrage d'un problème sur le terrain (par exemple, Groop, Ketokivi, Gupta et Holmström, 2017), ou sur l'exploration de modes de fonctionnement alternatifs, par exemple, grâce à de nouvelles technologies ( ex., Hedenstierna et al., 2019 ). Dans la recherche en science de conception exploratoire, la modélisation et la simulation jouent un rôle important, prenant la place de la mise en œuvre dans l'exploration des résultats (Hedenstierna et al., 2019). En outre, la théorie et la théorisation sont des méthodes permettant d'anticiper la meilleure façon de tester et de développer une solution qui n'a pas encore été testée sur le terrain pour être transférable et appliquée à des environnements au-delà de ceux où elle a été conçue.

Le processus de recherche exploratoire de cet article est présenté à la figure 1. La recherche a commencé à partir du problème de terrain de la compagnie de cas, Nordic Airline. Grâce à l'exploration et à la modélisation de la conception, les effets de la modification des principes d'ordonnancement de la maintenance en ligne pourraient être explorés, entraînant la proposition d'un nouveau type de tampon, intéressant la théorie de l'OM. Les principaux jalons et événements du processus de recherche ont consisté à recadrer le problème de fiabilité des départs en un problème de rééchelonnement (déplacement de l'accent de l'engagement dans la pratique vers l'exploration et la modélisation de la conception) en articulant la solution comme un tampon du frontlog par opposition à un retard (déplacement de l'accent de conception et modélisation à la recherche théorique et à la théorisation) et les résultats d'une simulation détaillée qui ont indiqué le potentiel d'améliorer à la fois la fiabilité des départs et la rentabilité des coûts de maintenance (en reportant l'attention sur la mise en œuvre et en surmontant les obstacles à la mise en œuvre).

L'engagement de recherche avec Nordic Airline a commencé en 2014 dans le cadre d'une grande initiative de recherche stratégique réunissant des chercheurs universitaires et l'industrie financée par l'agence de financement pour la technologie et l'innovation. La direction de l'organisation de maintenance cherchait des moyens d'améliorer la fiabilité des départs de leur flotte long-courrier et a invité les chercheurs universitaires à se joindre à la recherche. La compagnie aérienne exploite un réseau en étoile avec un avantage géographique pour relier l'Asie et l'Europe, soulignant l'importance stratégique de la flotte long-courrier et, par extension, la fiabilité des départs. L'avantage géographique du hub de la compagnie aérienne se traduit par l'une des utilisations de flotte les plus élevées pour les avions long-courriers, où les avions passent plus de temps dans les airs qu'au sol. En raison de la forte utilisation de la flotte, la fenêtre de maintenance typique au hub est limitée à quelques heures par jour, entre le moment où l'avion arrive au hub et le retour vers sa destination asiatique. La compagnie aérienne appelle cela la maintenance en rotation, et l'augmentation de la flexibilité des ressources dans cette opération était l'objectif initial de la recherche.

À la fin de l'engagement initial en 2015, en explorant des objectifs contradictoires à l'aide d'outils de processus de réflexion (Groop et al., 2017), la possibilité de modifier la planification de la maintenance a été identifiée comme une solution potentielle. La possibilité a d'abord été étudiée dans le contexte du processus de planification de la maintenance en ligne existant, dans le but de réduire la variabilité de la charge de travail dans les opérations de maintenance en rotation. Le constat a été que, pour la flotte long-courrier, une partie de la charge de travail programmée pouvait être planifiée afin qu'elle puisse être ultérieurement reportée de manière opportuniste, introduisant en effet à dessein une sur-maintenance. L'élaboration de l'effet de ce changement sur les coûts de maintenance a été la troisième phase du processus de recherche, la simulation détaillée, qui a été lancée en mai 2016. La quatrième étape du processus de recherche consistait à identifier ce qu'était cette nouvelle pratique de maintenance, d'un point de vue théorique. , et menée pour la rédaction de cet article de recherche, qui a commencé au début de 2017. Cette théorisation consistait à comparer à la fois notre conception et nos résultats avec un large corpus de littérature académique sur la gestion des opérations et de la maintenance. Actuellement, l'introduction de la solution proposée dans la pratique progresse dans le cadre d'un effort de numérisation plus large, avec une négociation en cours d'un rôle potentiel des chercheurs dans le projet. Les données recueillies pour la recherche par l'engagement dans la pratique et pour la modélisation sont résumées dans le tableau 2.

Descriptions des processus de maintenance

Documentation de conformité réglementaire

Rapports (performances de la flotte, effectifs, retards)

Extraits de documents utilisés dans les opérations (fiches de planification, instructions de travail, etc.)

Programmes de maintenance des aéronefs

Enregistrements des événements de maintenance (12 mois)

Données du programme de circulation (12 mois)

Notes des discussions informelles

Discussions ponctuelles pour clarifier les problèmes qui ont émergé lors de la modélisation

Notes de réunions et présentations des résultats

S'engager avec l'entreprise concernée pour résoudre son problème initial sur le terrain a lancé un processus de cadrage et de recadrage (Simon, 1996 ) qui a offert l'opportunité d'innover dans les opérations de maintenance en ligne des aéronefs. Être attentif aux cadres détenus par les acteurs du problème (Coghlan et Brannick, 2001) crée l'opportunité de recadrer les problèmes de terrain de manière innovante à des fins de conception exploratoire (Groop et al., 2017). La phase de modélisation de la recherche a d'abord étudié la relation entre la sur-maintenance et la variance de la charge de travail dans un cadre déterministe, en se concentrant uniquement sur la maintenance programmée (Öhman, Laine & Holmström, 2016. Pour l'étude initiale, nous avons mené cinq entretiens semi-directifs (chacun d'une durée de 1 à 2 heures) avec les planificateurs de maintenance pour les flottes long-courriers et court-courriers et les responsables des opérations, de la production et de la planification des ressources. Grâce à ces entretiens, nous avons acquis une compréhension approfondie de la fonction de planification de la maintenance de l'entreprise concernée. Nous avons également découvert heuristiques et principes non visibles dans la documentation opérationnelle. L'étude a montré des résultats prometteurs : une augmentation de 1 % de la charge de travail totale prévue pourrait entraîner une réduction jusqu'à 6 % de la variance de la charge de travail. Cependant, nous avons conclu que l'impact réel ne pouvait pas être évalué tandis que la variabilité naturelle de la demande causée par la charge de travail émergente a été négligée.

Through the engagement with practice and the initial modeling phase, we developed a rich, in-depth understanding of the case company context (cf. Forrester, 1992 ), based on both qualitative and quantitative data (Table 2). This understanding was crucial in empirical grounding of the simulation model presented here, and it allowed us to formulate the good problem, which is the key to success in any simulation project (Law, 2003 ). The simulation model then allowed us to explore the effect of the proposed buffer management approach in a stochastic setting.


2 réponses 2

I agree with everything from palacsint (7. could be discussed. If it is a requirement, then it is fine)
I will add some more thoughts.

This comment is not necessary. Even more, noone (with an IDE) will read comments in the import section.

As far as I see it, your implementation is a fixed size (FIFO) queue. If I am right, I would choose this name instead of CircularBuffer .
With this name, even if it is not well defined, I would expect some circularity. There is none. (Not for the caller, the inside details are not interesting for anyone using this class.)
One could even argument, that using java collection (implement an interface, using collection classes) would be a good way to integrate it inside the java world.

I would change the names, the array is in fact the buffer , put_idx the head , get_idx the tail , count the number of elements and size is not needed:

Do you need this method? If no, remove it. If you need it, it could be a good idea to clear the buffer, too. The garbage collector would appreciate this.

A typical and good name for a method returning a method is isSomething() or hasSomething() . So in this case isEmpty() , isFull() .

If we look at java collections, the typical and expected name would bet getSize()

I would throw an IllegalStateException exception. ArrayIndexOutOfBoundsException is not true, the buffer is full, it can not be out of bounds, unless the implementation is wrong.
In this case, the expected state is "not full", but it is "full".
Remark: Depending on the requirements, you could start to overwrite old entries. This would be typical for a circular buffer.

I would add some javadoc comments, at least to tell the caller about the exception he could catch.

This comment is already clear from the method signature.
If we look at java collections again, I would rename it to addAll .
Which is quite important if you try to add for example null . Does it go to insert(T element) or insert(T[] thearray) ? Should it be there?

This could be simplified, you do not need 2 complex cases:

And because the name and argument behavior of System.arraycopy is awful, I would introduce a small method. So anyone reading it could understand it without spending time on thinking about arraycopy :

If we look at java collections again, I would rename it too removeOldest() . Or if you want to be very specific removeAndGetOldest() .
It is not the typical expectation to remove the element if get is called. If you do so, add at least some javadoc comment indicating this behavior.
Exception: See above.

This is only a personal opinion: I would avoid using the postincrement operator overall. This case looks simple, but you can easily get complicated cases because of side effects in all languages.
And with current compilers, it does (in most of the scenarios) not make any change in size, speed or whatever.
So I would go for readability.


Acknowledgements and funding

We thank Jean David, Masayoshi Watada, Ary Hoffmann and Wenxia Zhang for providing fly strains, Rudolf Saegesser and Anina Pescatore for technical assistance, and Suzannah Rutherford for discussion. AW acknowledges support through Swiss National Science Foundation grants 315200-116814, 315200-119697, and 315230-129708, as well as through the YeastX project of SystemsX.ch, and the University Priority Research Program in Systems Biology at the University of Zurich.


ArcGIS Pro: Create polygons from outlines of unclosed lines

First a disclaimer: I have very little experience with ArcGIS, I usually use QGIS and only recently started using ArcGIS Pro.

I have a River dataset from the Natural Earth Site, then made its symbology thickness vary depending on its "strokeweig" attribute.

My goal is relatively simple: Creating a polygon that follows the outlines of this river line with variable thickness.

At first i saw two main ways of doing it:

Simply creating a polygon and drawing it (using the Freehand tool) so that it follows the outline of the rivers, however this is time consuming, and the fact the size of the river change when zooming prevents accurate drawing.

Exporting the river alone as a raster, then creating a polygon out of that raster, however I would have to reasign coordinates for this new polygon, which would bring some inacuracies.

-- Most of the Internet tutorials i saw recommended using the "Construct Polygon" tool, however it doesn't work on unclosed lines, and it only creates polygons out of the few rivers that join back. (Exemple here: https://i.imgur.com/CrTByTD.png https://i.imgur.com/ipt5hK8.png )

Furthermore, someone told me to use the "Convert features into graphics" tool, then reverse it with the "Convert graphics into feature", however, these tools only seem to be available on ArcMap, and not ArcGis Pro (and if i am mistaken and they are avaible, how does one access them?).

So to recap: Is there a way to directly (as automatically as possible) create a polygon out of the shape/outlines of these river line (with their symbology) without either having to draw polygons by hand or exporting it as a Raster image.

Can you buffer the lines and use strokeweig as the buffer value to get something like this?

Yes it is possible, as someone answered on another forum, it is quite contrivied however, i copied the answer in that comment:

Use option 1, but instead of freehand use the trace tool.

Thanks, i fear that may be the only way.

Is there a way to "freeze" the size of symbols/line thickness, so that when i zoom it doesn't resizes? Because simply increasing the thickness of the line also changes the shape of the outline.

Most Some of those should be available as a polygon layer somewhere. especially the Amazon. I'm investigating the availability of something and will report back.

Although to be fair the region i was the most interested in is Subsaharian africa.

I think buffering is going to be your best bet, but to elaborate on your other ideas:

Simply creating a polygon and drawing it (using the Freehand tool) so that it follows the outline of the rivers, however this is time consuming, and the fact the size of the river change when zooming prevents accurate drawing.

You can fix the zooming issue by setting a reference scale. Like, if you've got the symbology set up so that you like how it looks and you're at 1:100,000, you can set the reference scale to 1:100,000, and then the symbology will always render as though you were at 1:100,000 -- so when you zoom in, the symbology gets really big, which would make it easier for you to digitize or freehand, and when you zoom out, it gets really small, instead of actively re-sizing like it normally does. I still wouldn't recommend doing that though, because as you noted, it would take forever.

Exporting the river alone as a raster, then creating a polygon out of that raster, however I would have to reasign coordinates for this new polygon, which would bring some inacuracies.

This is going to ignore the symbology you've set and only make a raster with a single "line" of cells in it. The symbology is based on the layer (what you see in the table of contents, which includes the symbology), but most tools run off the underlying data. Same thing applies if you made the rivers all dashed lines the program is going to convert the data and give you a solid line, rather than converting the symbology and giving you pieces of a line.

[the buffer] is quite contrivied however

Those instructions are very thorough, but I think they make it sound harder than it really is. You're already using "strokeweight" (I'm gonna roll with that as the name of the column) to vary the line weight. You need to do the same thing to run the buffer tool, but unfortunately, while you're smart enough to turn those stroke weights into something that looks good, the buffer tool is not. You have to translate those stroke weights into distances that the buffer tool needs to run its calculations.

So like, let's say your biggest rivers have a stroke weight of 7, and you've made those 5pt lines in your map. Do some measuring in your map and figure out what you think an appropriate distance would be. Maybe at the scale you're currently at, where you think it looks good, that 5pt line measures out to

20km wide. (Setting a reference scale here would help you as you measure these distances). If you want a river that's 20km wide edge to edge, you would need to buffer the line by 10km. Ok, so now you know that strokeweight 7 = 10km buffer. So add a new column (field) to your data to hold these buffer distances. For every row that has a stroke weight of 7, you're going to fill in the buffer distance with a 10. (Don't worry about the units you can set those when you run the tool). You can use the "select by attributes" tool to select all the rows with a stroke weight of 7 at once, and you can use field calculator to copy your new value of 10 into all of those selected rows at once.

Then you just repeat that for each of your stroke weights -- figure out what the buffer distance would be for each of your stroke weights, then use select by attribute and field calculator to select and fill in the appropriate buffer distance for each stroke weight.

When all of the river segments have a buffer distance calculated, you can run the buffer tool and tell it to use the buffer distance field for the buffer distances.


Abstrait

Remnant urban forests are often popular sites for recreational activities such as hiking, biking and motorised recreation. This can result in the formation of extensive trail networks, fragmenting vegetation into patches separated by modified edge effects and ultimately contributing to the degradation of the ecosystem as a whole. Here we use a GIS approach to assess the extent and diversity of trail-based fragmentation across 17 remnants of endangered urban forest (total area 829 ha, Tall Open Blackbutt Forest) in southeast Queensland, Australia. Fourteen different trail types totalling 46.1 km were mapped with informal biking and hiking trails the most common (57%, 26.5 km). More than 47 ha (5.7%) of forest have been lost to trails and their edge effect, nearly equal to the area recently cleared for urban development. The degree of fragmentation in some remnants was in the same order of magnitude as found for some of the most popular nature-based recreation sites in the world. In localised areas, the fragmentation was particularly severe as a result of wide trails used by motorised recreation, but these trails were generally uncommon across the landscape (5%). Spatial regression revealed that the number of access points per remnant was positively correlated with the degree of fragmentation. We encourage more landscape-scale research into trail-based fragmentation due to its capacity to impact extensive areas of endangered ecosystems. Management should seek to minimise the creation of informal trails by hardening popular routes, instigating stakeholder collaboration and centralising visitor flow.


I ended up using bytearray as an input and output buffer. If found that if the output was something that doesn't buffer output (like a socket), then writing 77 bytes at a time would be very slow. Also my original code rounded the read size to be advantageous for base64, but not advantageous for MongoDB. It's better for the read size to match the MongoDB chunk size exactly. So the input is read into a bytearray with the exact size passed in, but then read in smaller base64 size chunks.

For 10 iterations of a 10 MB file (complete test), this version is up to 5 times faster than standard base64 with large buffer sizes (>969) when reading a file without buffering (like a socket). For small buffer sizes (

100) it is about the same or worse than standard base64.

The first thing I notice is that you are using Python2. This is almost certainly wrong. Python3 is faster for most applications, and Python2 is going EOL in 15 months.

Other than that, my main comments would be that this would probably benefit from async as this is an IO heavy function, so you could be doing the computation while waiting for a different IO task to finish.


Voir la vidéo: Unsupervised Classification of a satellite image using ArcGIS